Skip to content
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

[python] Fix Circular imports on inherited discriminators. #17886

Merged
merged 12 commits into from
Feb 20, 2024
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -927,10 +927,7 @@ private ModelsMap postProcessModelsMap(ModelsMap objs) {
// if super class
if (model.getDiscriminator() != null && model.getDiscriminator().getMappedModels() != null) {
moduleImports.add("typing", "Union");
Set<CodegenDiscriminator.MappedModel> discriminator = model.getDiscriminator().getMappedModels();
for (CodegenDiscriminator.MappedModel mappedModel : discriminator) {
postponedModelImports.add(mappedModel.getModelName());
}
moduleImports.add("importlib", "import_module");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -879,10 +879,6 @@ private ModelsMap postProcessModelsMap(ModelsMap objs) {
// if super class
if (model.getDiscriminator() != null && model.getDiscriminator().getMappedModels() != null) {
typingImports.add("Union");
Set<CodegenDiscriminator.MappedModel> discriminator = model.getDiscriminator().getMappedModels();
for (CodegenDiscriminator.MappedModel mappedModel : discriminator) {
postponedModelImports.add(mappedModel.getModelName());
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ import json
{{{.}}}
{{/vendorExtensions.x-py-model-imports}}

{{#hasChildren}}{{#discriminator}}
Copy link
Member

@wing328 wing328 Feb 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the PR.

minor suggestions:

  1. use the following to avoid the empty line break

{{#hasChildren}}
{{#discriminator}}
...
{{/discriminator}}
{{/hasChildren}}

  1. for line 22 (empty line), move it between line 20 and 21 so that it will only be included when both hasChilden and discriminator are non-emtpy (or true)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This issue has been fixed.

{{! If this model is a super class, importlib is used. So import the necessary modules for the type here. }}
from typing import TYPE_CHECKING
from importlib import import_module
if TYPE_CHECKING:
{{#mappedModels}}
from {{packageName}}.models.{{model.classVarName}} import {{modelName}}
{{/mappedModels}}
{{/discriminator}}{{/hasChildren}}

class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}):
"""
{{#description}}{{{description}}} # noqa: E501{{/description}}{{^description}}{{{classname}}}{{/description}}
Expand Down Expand Up @@ -222,13 +232,13 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}
{{#discriminator}}
# look up the object type based on discriminator mapping
object_type = cls.get_discriminator_value(obj)
if object_type:
klass = globals()[object_type]
return klass.from_dict(obj)
else:
raise ValueError("{{{classname}}} failed to lookup discriminator value from " +
json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name +
", mapping: " + json.dumps(cls.__discriminator_value_class_map))
{{#mappedModels}}
if object_type == '{{{mappingName}}}':
return import_module("{{packageName}}.models.{{model.classVarName}}").{{modelName}}.from_dict(obj)
{{/mappedModels}}
raise ValueError("{{{classname}}} failed to lookup discriminator value from " +
json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name +
", mapping: " + json.dumps(cls.__discriminator_value_class_map))
{{/discriminator}}
{{/hasChildren}}
{{^hasChildren}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ import json
from typing import Optional, Set
from typing_extensions import Self

{{#hasChildren}}{{#discriminator}}
{{! If this model is a super class, importlib is used. So import the necessary modules for the type here. }}
from typing import TYPE_CHECKING
if TYPE_CHECKING:
{{#mappedModels}}
from {{packageName}}.models.{{model.classVarName}} import {{modelName}}
{{/mappedModels}}
{{/discriminator}}{{/hasChildren}}

class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}):
"""
{{#description}}{{{description}}}{{/description}}{{^description}}{{{classname}}}{{/description}}
Expand Down Expand Up @@ -113,7 +122,7 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}
return json.dumps(self.to_dict())

@classmethod
def from_json(cls, json_str: str) -> Optional[{{^hasChildren}}Self{{/hasChildren}}{{#hasChildren}}{{#discriminator}}Union[{{#children}}Self{{^-last}}, {{/-last}}{{/children}}]{{/discriminator}}{{^discriminator}}Self{{/discriminator}}{{/hasChildren}}]:
def from_json(cls, json_str: str) -> Optional[{{^hasChildren}}Self{{/hasChildren}}{{#hasChildren}}{{#discriminator}}Union[{{#mappedModels}}{{{modelName}}}{{^-last}}, {{/-last}}{{/mappedModels}}]{{/discriminator}}{{^discriminator}}Self{{/discriminator}}{{/hasChildren}}]:
"""Create an instance of {{{classname}}} from a JSON string"""
return cls.from_dict(json.loads(json_str))

Expand Down Expand Up @@ -236,18 +245,19 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}

{{#hasChildren}}
@classmethod
def from_dict(cls, obj: Dict[str, Any]) -> Optional[{{#discriminator}}Union[{{#children}}Self{{^-last}}, {{/-last}}{{/children}}]{{/discriminator}}{{^discriminator}}Self{{/discriminator}}]:
def from_dict(cls, obj: Dict[str, Any]) -> Optional[{{#discriminator}}Union[{{#mappedModels}}{{{modelName}}}{{^-last}}, {{/-last}}{{/mappedModels}}]{{/discriminator}}{{^discriminator}}Self{{/discriminator}}]:
"""Create an instance of {{{classname}}} from a dict"""
{{#discriminator}}
# look up the object type based on discriminator mapping
object_type = cls.get_discriminator_value(obj)
if object_type:
klass = globals()[object_type]
return klass.from_dict(obj)
else:
raise ValueError("{{{classname}}} failed to lookup discriminator value from " +
json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name +
", mapping: " + json.dumps(cls.__discriminator_value_class_map))
{{#mappedModels}}
if object_type == '{{{mappingName}}}':
return import_module("{{packageName}}.models.{{model.classVarName}}").{{modelName}}.from_dict(obj)
{{/mappedModels}}

raise ValueError("{{{classname}}} failed to lookup discriminator value from " +
json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name +
", mapping: " + json.dumps(cls.__discriminator_value_class_map))
{{/discriminator}}
{{/hasChildren}}
{{^hasChildren}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,20 @@ components:
required:
- id
- activity
DiscriminatorAllOfSuper:
type: object
required:
- elementType
discriminator:
propertyName: elementType
properties:
elementType:
type: string
DiscriminatorAllOfSub:
allOf:
- $ref: '#/components/schemas/DiscriminatorAllOfSuper'
- type: object
properties: {}
Pet:
type: object
required:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class Bird(BaseModel):
"""
Bird
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class Category(BaseModel):
"""
Category
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from typing import Optional, Set
from typing_extensions import Self



class DataQuery(Query):
"""
DataQuery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from typing import Optional, Set
from typing_extensions import Self



class DefaultValue(BaseModel):
"""
to test the default value of properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from typing import Optional, Set
from typing_extensions import Self



class NumberPropertiesOnly(BaseModel):
"""
NumberPropertiesOnly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from typing import Optional, Set
from typing_extensions import Self



class Pet(BaseModel):
"""
Pet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class Query(BaseModel):
"""
Query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class Tag(BaseModel):
"""
Tag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class TestQueryStyleDeepObjectExplodeTrueObjectAllOfQueryObjectParameter(BaseModel):
"""
TestQueryStyleDeepObjectExplodeTrueObjectAllOfQueryObjectParameter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter(BaseModel):
"""
TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from typing import Optional
from pydantic import BaseModel, StrictStr



class Bird(BaseModel):
"""
Bird
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from typing import Optional
from pydantic import BaseModel, StrictInt, StrictStr



class Category(BaseModel):
"""
Category
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from pydantic import Field, StrictStr
from openapi_client.models.query import Query



class DataQuery(Query):
"""
DataQuery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from pydantic import BaseModel, StrictInt, StrictStr, conlist, validator
from openapi_client.models.string_enum_ref import StringEnumRef



class DefaultValue(BaseModel):
"""
to test the default value of properties # noqa: E501
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from typing import Optional, Union
from pydantic import BaseModel, StrictFloat, StrictInt, confloat, conint



class NumberPropertiesOnly(BaseModel):
"""
NumberPropertiesOnly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from openapi_client.models.category import Category
from openapi_client.models.tag import Tag



class Pet(BaseModel):
"""
Pet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from typing import List, Optional
from pydantic import BaseModel, Field, StrictInt, StrictStr, conlist, validator



class Query(BaseModel):
"""
Query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from typing import Optional
from pydantic import BaseModel, StrictInt, StrictStr



class Tag(BaseModel):
"""
Tag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from typing import Optional
from pydantic import BaseModel, StrictInt, StrictStr



class TestQueryStyleDeepObjectExplodeTrueObjectAllOfQueryObjectParameter(BaseModel):
"""
TestQueryStyleDeepObjectExplodeTrueObjectAllOfQueryObjectParameter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from typing import List, Optional
from pydantic import BaseModel, StrictStr, conlist



class TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter(BaseModel):
"""
TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter
Expand Down
2 changes: 2 additions & 0 deletions samples/client/echo_api/python/openapi_client/models/bird.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class Bird(BaseModel):
"""
Bird
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class Category(BaseModel):
"""
Category
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from typing import Optional, Set
from typing_extensions import Self



class DataQuery(Query):
"""
DataQuery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from typing import Optional, Set
from typing_extensions import Self



class DefaultValue(BaseModel):
"""
to test the default value of properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from typing import Optional, Set
from typing_extensions import Self



class NumberPropertiesOnly(BaseModel):
"""
NumberPropertiesOnly
Expand Down
2 changes: 2 additions & 0 deletions samples/client/echo_api/python/openapi_client/models/pet.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from typing import Optional, Set
from typing_extensions import Self



class Pet(BaseModel):
"""
Pet
Expand Down
2 changes: 2 additions & 0 deletions samples/client/echo_api/python/openapi_client/models/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class Query(BaseModel):
"""
Query
Expand Down
2 changes: 2 additions & 0 deletions samples/client/echo_api/python/openapi_client/models/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class Tag(BaseModel):
"""
Tag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from typing import Optional, Set
from typing_extensions import Self



class TestQueryStyleDeepObjectExplodeTrueObjectAllOfQueryObjectParameter(BaseModel):
"""
TestQueryStyleDeepObjectExplodeTrueObjectAllOfQueryObjectParameter
Expand Down
Loading
Loading