diff --git a/.github/workflows/python-test.yaml b/.github/workflows/python-test.yaml index e22fb2f..b645d55 100644 --- a/.github/workflows/python-test.yaml +++ b/.github/workflows/python-test.yaml @@ -24,7 +24,7 @@ jobs: python -m pip install --upgrade pip python -m pip install flake8 pip install setuptools wheel - pip install -r requirements.txt + pip install -r requirements_test.txt pip install . - name: Lint with flake8 run: | diff --git a/pyproject.toml b/pyproject.toml index 3ee6210..5a912ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "crimson-auto-pydantic" -version = "0.1.0" +version = "0.1.2" description = "Template Tools" readme = "README.md" authors = [ @@ -23,7 +23,8 @@ classifiers = [ dependencies = [ "pydantic", "crimson-code-extractor", - "crimson-ast-dev-tool" + "crimson-ast-dev-tool", + "inflection" ] requires-python = ">=3.9" diff --git a/requirements.txt b/requirements.txt index 1538f89..0e44c3c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,4 @@ -inflection -jinja2 +pydantic crimson-code-extractor crimson-ast-dev-tool -crimson-file-loader -pytest -pytest-cov +inflection diff --git a/requirements_dev.txt b/requirements_dev.txt new file mode 100644 index 0000000..e69de29 diff --git a/requirements_test.txt b/requirements_test.txt new file mode 100644 index 0000000..9955dec --- /dev/null +++ b/requirements_test.txt @@ -0,0 +1,2 @@ +pytest +pytest-cov diff --git a/src/crimson/auto_pydantic/generator.py b/src/crimson/auto_pydantic/generator.py index 71877cf..653feb8 100644 --- a/src/crimson/auto_pydantic/generator.py +++ b/src/crimson/auto_pydantic/generator.py @@ -6,6 +6,38 @@ def generate_constructor(function_node: ast.FunctionDef, indent: int = 4) -> str: + """ + # generate_constructor + + ## Description + The `generate_constructor` function generates a constructor method for a Pydantic model based on the given function node. It creates an `__init__` method that initializes the model's attributes using the function's parameters. + + ## Parameters + - `function_node` (ast.FunctionDef): An Abstract Syntax Tree (AST) node representing the function for which the constructor is being generated. + - `indent` (int, optional): The number of spaces to use for indentation. Default is 4. + + ## Returns + - `str`: A string containing the generated constructor method. + + ## Functionality + 1. Extracts the function specification from the given AST node. + 2. Determines if the function is already an `__init__` method or a regular function. + 3. Generates the method signature with appropriate parameters. + 4. Creates a `super().__init__()` call to initialize the Pydantic model. + 5. Includes all function parameters in the `super().__init__()` call, except for `self` and `cls`. + + ## Example Output + ```python + def __init__(self, arg1: int, arg2: str = 'default'): + super().__init__(arg1=arg1, arg2=arg2) + ``` + + ## Notes + - The function handles both regular functions and existing `__init__` methods. + - It properly handles default values and type annotations from the original function. + - The generated constructor is compatible with Pydantic's model initialization. + """ + func_spec = extract.extract_func_spec(function_node) indent = " " * indent if func_spec.name == "__init__": diff --git a/src/crimson/auto_pydantic/validator.py b/src/crimson/auto_pydantic/validator.py index d9474ea..0070924 100644 --- a/src/crimson/auto_pydantic/validator.py +++ b/src/crimson/auto_pydantic/validator.py @@ -1,6 +1,6 @@ from typing import Callable, Dict, Any import ast -from crimson.ast_dev_tool import get_first_node +from crimson.ast_dev_tool import collect_nodes from crimson.auto_pydantic.generator import generate_input_props, _generate_input_props_name from inspect import getsource import typing @@ -31,7 +31,7 @@ def _prepare_namespace(currentframe, args, kwargs) -> Dict[str, Any]: def _get_function_node(func: Callable) -> ast.FunctionDef: func_source = getsource(func) - return get_first_node(func_source, ast.FunctionDef) + return collect_nodes(func_source, ast.FunctionDef)[0] def _get_or_create_input_props(