-
-
Notifications
You must be signed in to change notification settings - Fork 280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Importing generated code results in a circular dependency #836
Comments
@gal-gocredd did you find a workaround for this? |
If someone has an idea to resolve the circular dependency structure then could please post it? |
I just wrote a post-processing script to get around this by moving the imports of other models to the bottom of the script before any calls to I've still got some testing to do, but it at least allows me to import modules with circular imports without errors. It did require me to "trick" dataclass-codegen into putting each model in its own file to reliably move all of the imports before that method call. I would propose:
Things I still need to look into before I confidently declare this a viable solution:
|
@noddycode would you care to share your post-processing script? Your quick mockup link has expired. Unfortunately running into the same issue here after generating models based off the ConnectWise OpenAPI spec. |
Unfortunately the code is proprietary, but I can write up a summary of what it does later today. In the meantime, one thing I would/will eventually change about my script is using the TYPE_CHECKING boolean along with annotations from future instead of moving imports to the bottom. See here: https://stackoverflow.com/a/72667915 Given some time in the next few weeks, I'd like to try and contribute something that does this during generation. |
Hey, I'm trying to the create models for ms adaptive cards (schema here) since the python sdk is not available yet. It causes circular imports for this schema too. Any solutions for this? I ended up creating a thin wrapper by hand for models which I use. |
I might have another test case (feel free to create another issue if needed).
The generated code has clear circular dependencies. |
- Resolve circular imports (koxudaxi/datamodel-code-generator#836) - Use kw_only=True (koxudaxi/datamodel-code-generator#1919)
Due to issues with circular references I wrote a small program to transform the schema source to a format that could be generated to a single Python file. There were still issues with type references that were not fixed with This fixes the issue for me currently - leaving it here as a hack in case it might help someone else. YMMV. def transform_python_source_internal_forward_references(
python_source: str,
) -> str:
import ast
class Parentage(ast.NodeTransformer):
parent = None
def visit(self, node):
node.parent = self.parent
self.parent = node
node = super().visit(node)
if isinstance(node, ast.AST):
self.parent = node.parent
return node
class TransformForwardDeclarations(ast.NodeTransformer):
def visit_Name(self, node):
# NB: Does not transform names which are direct class bases,
# or names which are used as attributes, e.g.: some_model.model_rebuild()
replace_name_with_forward_declaration = (
node.id in python_source_class_names
and node.ctx
and isinstance(node.ctx, ast.Load)
and (
not node.parent
or not isinstance(node.parent, (ast.ClassDef, ast.Attribute))
)
)
if replace_name_with_forward_declaration:
return ast.Constant(value=node.id)
else:
return node
python_source_ast = ast.parse(python_source)
# Add parent information to individual nodes:
Parentage().visit(python_source_ast)
# Find class names defined in source:
python_source_class_names = [
node.name
for node in ast.walk(python_source_ast)
if isinstance(node, ast.ClassDef)
]
# Replace references to class names with forward declarations:
python_source_ast = ast.fix_missing_locations(
TransformForwardDeclarations().visit(python_source_ast)
)
return ast.unparse(python_source_ast) |
Describe the bug
I'm trying to use
datamodel-codegen
to generate Pydantic models from Stripe's openapi. The generation itself succeeds but trying to import the generated package results in an import error due to circular dependency:It looks like the generation puts every model that includes a
.
for exampleissuing.authorization
in its own file, in this exampleissuing.py
, and every model that doesn't - in the__init__.py
file, resulting in some models from the init trying to import files from other files, and those other files trying to import from the init.Trying to generate everything into one file fails with
Modular references require an output directory, not a file
.To Reproduce
Example schema:
I tried using both the
.yaml
and.json
just in case, both result in the same error.Used commandline:
Expected behavior
I'd expect to be able to import the generated code
Version:
The text was updated successfully, but these errors were encountered: