diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_utils.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_utils.mustache index c9a527ab6fe..49ad6f35e39 100644 --- a/modules/openapi-generator/src/main/resources/python/python-experimental/model_utils.mustache +++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_utils.mustache @@ -83,26 +83,22 @@ class OpenApiModel(object): cls.discriminator is None or cls in visited_composed_classes ): - # This openapi schema (cls) does not have a discriminator - # Or we have already visited this class before and are sure that we - # want to instantiate it this time. + # Use case 1: this openapi schema (cls) does not have a discriminator + # Use case 2: we have already visited this class before and are sure that we + # want to instantiate it this time. We have visited this class deserializing + # a payload with a discriminator. During that process we traveled through + # this class but did not make an instance of it. Now we are making an + # instance of a composed class which contains cls in it, so this time make an instance of cls. # - # If we are making an instance of a composed schema Descendent - # which allOf includes Ancestor, then Ancestor contains - # a discriminator that includes Descendent. - # So if we make an instance of Descendent, we have to make an - # instance of Ancestor to hold the allOf properties. - # This code detects that use case and makes the instance of Ancestor - # For example: - # When making an instance of Dog, _visited_composed_classes = (Dog,) - # then we make an instance of Animal to include in dog._composed_instances - # so when we are here, cls is Animal - # cls.discriminator != None - # cls not in _visited_composed_classes - # new_cls = Dog - # but we know we know that we already have Dog - # because it is in visited_composed_classes - # so make Animal here + # Here's an example of use case 2: If Animal has a discriminator + # petType and we pass in "Dog", and the class Dog + # allOf includes Animal, we move through Animal + # once using the discriminator, and pick Dog. + # Then in the composed schema dog Dog, we will make an instance of the + # Animal class (because Dal has allOf: Animal) but this time we won't travel + # through Animal's discriminator because we passed in + # _visited_composed_classes = (Animal,) + return super(OpenApiModel, cls).__new__(cls) # Get the name and value of the discriminator property. @@ -141,7 +137,22 @@ class OpenApiModel(object): ) if new_cls in visited_composed_classes: - # if we are coming from the chosen new_cls use cls instead + # if we are making an instance of a composed schema Descendent + # which allOf includes Ancestor, then Ancestor contains + # a discriminator that includes Descendent. + # So if we make an instance of Descendent, we have to make an + # instance of Ancestor to hold the allOf properties. + # This code detects that use case and makes the instance of Ancestor + # For example: + # When making an instance of Dog, _visited_composed_classes = (Dog,) + # then we make an instance of Animal to include in dog._composed_instances + # so when we are here, cls is Animal + # cls.discriminator != None + # cls not in _visited_composed_classes + # new_cls = Dog + # but we know we know that we already have Dog + # because it is in visited_composed_classes + # so make Animal here return super(OpenApiModel, cls).__new__(cls) oneof_anyof_child = new_cls in oneof_anyof_classes @@ -766,18 +777,20 @@ def get_discriminator_class(model_class, used_model_class = class_name_to_discr_class.get(discr_value) if used_model_class is None: # We didn't find a discriminated class in class_name_to_discr_class. + # So look in the ancestor or descendant discriminators # The discriminator mapping may exist in a descendant (anyOf, oneOf) # or ancestor (allOf). - # Ancestor example: in the "Dog -> Mammal -> Chordate -> Animal" + # Ancestor example: in the GrandparentAnimal -> ParentPet -> ChildCat # hierarchy, the discriminator mappings may be defined at any level - # in the hieararchy. - # Descendant example: a schema is oneOf[Plant, Mammal], and each - # oneOf child may itself be an allOf with some arbitrary hierarchy, - # and a graph traversal is required to find the discriminator. - composed_children = model_class._composed_schemas.get('oneOf', ()) + \ - model_class._composed_schemas.get('anyOf', ()) + \ - model_class._composed_schemas.get('allOf', ()) - for cls in composed_children: + # in the hierarchy. + # Descendant example: mammal -> whale/zebra/Pig -> BasquePig/DanishPig + # if we try to make BasquePig from mammal, we need to travel through + # the oneOf descendant discriminators to find BasquePig + descendant_classes = model_class._composed_schemas.get('oneOf', ()) + \ + model_class._composed_schemas.get('anyOf', ()) + ancestor_classes = model_class._composed_schemas.get('allOf', ()) + possible_classes = descendant_classes + ancestor_classes + for cls in possible_classes: # Check if the schema has inherited discriminators. if hasattr(cls, 'discriminator') and cls.discriminator is not None: used_model_class = get_discriminator_class( diff --git a/modules/openapi-generator/src/test/resources/3_0/python-experimental/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml b/modules/openapi-generator/src/test/resources/3_0/python-experimental/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml index 9e01283cc8c..a744bd126fa 100644 --- a/modules/openapi-generator/src/test/resources/3_0/python-experimental/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/python-experimental/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml @@ -1833,11 +1833,9 @@ components: oneOf: - $ref: '#/components/schemas/whale' - $ref: '#/components/schemas/zebra' + - $ref: '#/components/schemas/Pig' discriminator: propertyName: className - mapping: - whale: '#/components/schemas/whale' - zebra: '#/components/schemas/zebra' whale: type: object properties: @@ -1862,6 +1860,26 @@ components: type: string required: - className + Pig: + oneOf: + - $ref: '#/components/schemas/BasquePig' + - $ref: '#/components/schemas/DanishPig' + discriminator: + propertyName: className + BasquePig: + type: object + properties: + className: + type: string + required: + - className + DanishPig: + type: object + properties: + className: + type: string + required: + - className gmFruit: properties: color: @@ -1992,26 +2010,23 @@ components: allOf: - $ref: '#/components/schemas/ShapeInterface' - $ref: '#/components/schemas/QuadrilateralInterface' - # The following hierarchy is used to test discriminators - # that require recursive lookups. - biology.Chordate: + GrandparentAnimal: type: object - discriminator: - propertyName: className required: - - className + - pet_type properties: - className: + pet_type: type: string - biology.Reptile: + discriminator: + propertyName: pet_type + ParentPet: + type: object allOf: - - $ref: '#/components/schemas/biology.Chordate' - biology.Mammal: + - $ref: '#/components/schemas/GrandparentAnimal' + ChildCat: allOf: - - $ref: '#/components/schemas/biology.Chordate' - biology.Primate: - allOf: - - $ref: '#/components/schemas/biology.Mammal' - biology.Hominid: - allOf: - - $ref: '#/components/schemas/biology.Primate' + - $ref: '#/components/schemas/ParentPet' + - type: object + properties: + name: + type: string \ No newline at end of file diff --git a/samples/client/petstore/python-experimental/petstore_api/model_utils.py b/samples/client/petstore/python-experimental/petstore_api/model_utils.py index 91225e19fcb..1b690f28bdd 100644 --- a/samples/client/petstore/python-experimental/petstore_api/model_utils.py +++ b/samples/client/petstore/python-experimental/petstore_api/model_utils.py @@ -155,26 +155,22 @@ class OpenApiModel(object): cls.discriminator is None or cls in visited_composed_classes ): - # This openapi schema (cls) does not have a discriminator - # Or we have already visited this class before and are sure that we - # want to instantiate it this time. + # Use case 1: this openapi schema (cls) does not have a discriminator + # Use case 2: we have already visited this class before and are sure that we + # want to instantiate it this time. We have visited this class deserializing + # a payload with a discriminator. During that process we traveled through + # this class but did not make an instance of it. Now we are making an + # instance of a composed class which contains cls in it, so this time make an instance of cls. # - # If we are making an instance of a composed schema Descendent - # which allOf includes Ancestor, then Ancestor contains - # a discriminator that includes Descendent. - # So if we make an instance of Descendent, we have to make an - # instance of Ancestor to hold the allOf properties. - # This code detects that use case and makes the instance of Ancestor - # For example: - # When making an instance of Dog, _visited_composed_classes = (Dog,) - # then we make an instance of Animal to include in dog._composed_instances - # so when we are here, cls is Animal - # cls.discriminator != None - # cls not in _visited_composed_classes - # new_cls = Dog - # but we know we know that we already have Dog - # because it is in visited_composed_classes - # so make Animal here + # Here's an example of use case 2: If Animal has a discriminator + # petType and we pass in "Dog", and the class Dog + # allOf includes Animal, we move through Animal + # once using the discriminator, and pick Dog. + # Then in the composed schema dog Dog, we will make an instance of the + # Animal class (because Dal has allOf: Animal) but this time we won't travel + # through Animal's discriminator because we passed in + # _visited_composed_classes = (Animal,) + return super(OpenApiModel, cls).__new__(cls) # Get the name and value of the discriminator property. @@ -213,7 +209,22 @@ class OpenApiModel(object): ) if new_cls in visited_composed_classes: - # if we are coming from the chosen new_cls use cls instead + # if we are making an instance of a composed schema Descendent + # which allOf includes Ancestor, then Ancestor contains + # a discriminator that includes Descendent. + # So if we make an instance of Descendent, we have to make an + # instance of Ancestor to hold the allOf properties. + # This code detects that use case and makes the instance of Ancestor + # For example: + # When making an instance of Dog, _visited_composed_classes = (Dog,) + # then we make an instance of Animal to include in dog._composed_instances + # so when we are here, cls is Animal + # cls.discriminator != None + # cls not in _visited_composed_classes + # new_cls = Dog + # but we know we know that we already have Dog + # because it is in visited_composed_classes + # so make Animal here return super(OpenApiModel, cls).__new__(cls) oneof_anyof_child = new_cls in oneof_anyof_classes @@ -1033,18 +1044,20 @@ def get_discriminator_class(model_class, used_model_class = class_name_to_discr_class.get(discr_value) if used_model_class is None: # We didn't find a discriminated class in class_name_to_discr_class. + # So look in the ancestor or descendant discriminators # The discriminator mapping may exist in a descendant (anyOf, oneOf) # or ancestor (allOf). - # Ancestor example: in the "Dog -> Mammal -> Chordate -> Animal" + # Ancestor example: in the GrandparentAnimal -> ParentPet -> ChildCat # hierarchy, the discriminator mappings may be defined at any level - # in the hieararchy. - # Descendant example: a schema is oneOf[Plant, Mammal], and each - # oneOf child may itself be an allOf with some arbitrary hierarchy, - # and a graph traversal is required to find the discriminator. - composed_children = model_class._composed_schemas.get('oneOf', ()) + \ - model_class._composed_schemas.get('anyOf', ()) + \ - model_class._composed_schemas.get('allOf', ()) - for cls in composed_children: + # in the hierarchy. + # Descendant example: mammal -> whale/zebra/Pig -> BasquePig/DanishPig + # if we try to make BasquePig from mammal, we need to travel through + # the oneOf descendant discriminators to find BasquePig + descendant_classes = model_class._composed_schemas.get('oneOf', ()) + \ + model_class._composed_schemas.get('anyOf', ()) + ancestor_classes = model_class._composed_schemas.get('allOf', ()) + possible_classes = descendant_classes + ancestor_classes + for cls in possible_classes: # Check if the schema has inherited discriminators. if hasattr(cls, 'discriminator') and cls.discriminator is not None: used_model_class = get_discriminator_class( diff --git a/samples/openapi3/client/petstore/python-experimental/.openapi-generator/FILES b/samples/openapi3/client/petstore/python-experimental/.openapi-generator/FILES index e650f1d87aa..378e6965acc 100644 --- a/samples/openapi3/client/petstore/python-experimental/.openapi-generator/FILES +++ b/samples/openapi3/client/petstore/python-experimental/.openapi-generator/FILES @@ -14,18 +14,17 @@ docs/ArrayOfNumberOnly.md docs/ArrayTest.md docs/Banana.md docs/BananaReq.md -docs/BiologyChordate.md -docs/BiologyHominid.md -docs/BiologyMammal.md -docs/BiologyPrimate.md -docs/BiologyReptile.md +docs/BasquePig.md docs/Capitalization.md docs/Cat.md docs/CatAllOf.md docs/Category.md +docs/ChildCat.md +docs/ChildCatAllOf.md docs/ClassModel.md docs/Client.md docs/ComplexQuadrilateral.md +docs/DanishPig.md docs/DefaultApi.md docs/Dog.md docs/DogAllOf.md @@ -43,6 +42,7 @@ docs/FormatTest.md docs/Fruit.md docs/FruitReq.md docs/GmFruit.md +docs/GrandparentAnimal.md docs/HasOnlyReadOnly.md docs/HealthCheckResult.md docs/InlineObject.md @@ -69,8 +69,10 @@ docs/OuterEnum.md docs/OuterEnumDefaultValue.md docs/OuterEnumInteger.md docs/OuterEnumIntegerDefaultValue.md +docs/ParentPet.md docs/Pet.md docs/PetApi.md +docs/Pig.md docs/Quadrilateral.md docs/QuadrilateralInterface.md docs/ReadOnlyFirst.md @@ -115,18 +117,17 @@ petstore_api/models/array_of_number_only.py petstore_api/models/array_test.py petstore_api/models/banana.py petstore_api/models/banana_req.py -petstore_api/models/biology_chordate.py -petstore_api/models/biology_hominid.py -petstore_api/models/biology_mammal.py -petstore_api/models/biology_primate.py -petstore_api/models/biology_reptile.py +petstore_api/models/basque_pig.py petstore_api/models/capitalization.py petstore_api/models/cat.py petstore_api/models/cat_all_of.py petstore_api/models/category.py +petstore_api/models/child_cat.py +petstore_api/models/child_cat_all_of.py petstore_api/models/class_model.py petstore_api/models/client.py petstore_api/models/complex_quadrilateral.py +petstore_api/models/danish_pig.py petstore_api/models/dog.py petstore_api/models/dog_all_of.py petstore_api/models/drawing.py @@ -141,6 +142,7 @@ petstore_api/models/format_test.py petstore_api/models/fruit.py petstore_api/models/fruit_req.py petstore_api/models/gm_fruit.py +petstore_api/models/grandparent_animal.py petstore_api/models/has_only_read_only.py petstore_api/models/health_check_result.py petstore_api/models/inline_object.py @@ -167,7 +169,9 @@ petstore_api/models/outer_enum.py petstore_api/models/outer_enum_default_value.py petstore_api/models/outer_enum_integer.py petstore_api/models/outer_enum_integer_default_value.py +petstore_api/models/parent_pet.py petstore_api/models/pet.py +petstore_api/models/pig.py petstore_api/models/quadrilateral.py petstore_api/models/quadrilateral_interface.py petstore_api/models/read_only_first.py diff --git a/samples/openapi3/client/petstore/python-experimental/README.md b/samples/openapi3/client/petstore/python-experimental/README.md index 845aef4aa69..9827e98d2a1 100644 --- a/samples/openapi3/client/petstore/python-experimental/README.md +++ b/samples/openapi3/client/petstore/python-experimental/README.md @@ -133,18 +133,17 @@ Class | Method | HTTP request | Description - [array_test.ArrayTest](docs/ArrayTest.md) - [banana.Banana](docs/Banana.md) - [banana_req.BananaReq](docs/BananaReq.md) - - [biology_chordate.BiologyChordate](docs/BiologyChordate.md) - - [biology_hominid.BiologyHominid](docs/BiologyHominid.md) - - [biology_mammal.BiologyMammal](docs/BiologyMammal.md) - - [biology_primate.BiologyPrimate](docs/BiologyPrimate.md) - - [biology_reptile.BiologyReptile](docs/BiologyReptile.md) + - [basque_pig.BasquePig](docs/BasquePig.md) - [capitalization.Capitalization](docs/Capitalization.md) - [cat.Cat](docs/Cat.md) - [cat_all_of.CatAllOf](docs/CatAllOf.md) - [category.Category](docs/Category.md) + - [child_cat.ChildCat](docs/ChildCat.md) + - [child_cat_all_of.ChildCatAllOf](docs/ChildCatAllOf.md) - [class_model.ClassModel](docs/ClassModel.md) - [client.Client](docs/Client.md) - [complex_quadrilateral.ComplexQuadrilateral](docs/ComplexQuadrilateral.md) + - [danish_pig.DanishPig](docs/DanishPig.md) - [dog.Dog](docs/Dog.md) - [dog_all_of.DogAllOf](docs/DogAllOf.md) - [drawing.Drawing](docs/Drawing.md) @@ -159,6 +158,7 @@ Class | Method | HTTP request | Description - [fruit.Fruit](docs/Fruit.md) - [fruit_req.FruitReq](docs/FruitReq.md) - [gm_fruit.GmFruit](docs/GmFruit.md) + - [grandparent_animal.GrandparentAnimal](docs/GrandparentAnimal.md) - [has_only_read_only.HasOnlyReadOnly](docs/HasOnlyReadOnly.md) - [health_check_result.HealthCheckResult](docs/HealthCheckResult.md) - [inline_object.InlineObject](docs/InlineObject.md) @@ -185,7 +185,9 @@ Class | Method | HTTP request | Description - [outer_enum_default_value.OuterEnumDefaultValue](docs/OuterEnumDefaultValue.md) - [outer_enum_integer.OuterEnumInteger](docs/OuterEnumInteger.md) - [outer_enum_integer_default_value.OuterEnumIntegerDefaultValue](docs/OuterEnumIntegerDefaultValue.md) + - [parent_pet.ParentPet](docs/ParentPet.md) - [pet.Pet](docs/Pet.md) + - [pig.Pig](docs/Pig.md) - [quadrilateral.Quadrilateral](docs/Quadrilateral.md) - [quadrilateral_interface.QuadrilateralInterface](docs/QuadrilateralInterface.md) - [read_only_first.ReadOnlyFirst](docs/ReadOnlyFirst.md) diff --git a/samples/openapi3/client/petstore/python-experimental/docs/BiologyMammal.md b/samples/openapi3/client/petstore/python-experimental/docs/BasquePig.md similarity index 90% rename from samples/openapi3/client/petstore/python-experimental/docs/BiologyMammal.md rename to samples/openapi3/client/petstore/python-experimental/docs/BasquePig.md index 5f625ab888b..0e8f8bb27fb 100644 --- a/samples/openapi3/client/petstore/python-experimental/docs/BiologyMammal.md +++ b/samples/openapi3/client/petstore/python-experimental/docs/BasquePig.md @@ -1,4 +1,4 @@ -# biology_mammal.BiologyMammal +# basque_pig.BasquePig ## Properties Name | Type | Description | Notes diff --git a/samples/openapi3/client/petstore/python-experimental/docs/ChildCat.md b/samples/openapi3/client/petstore/python-experimental/docs/ChildCat.md new file mode 100644 index 00000000000..8f5ea4b2ced --- /dev/null +++ b/samples/openapi3/client/petstore/python-experimental/docs/ChildCat.md @@ -0,0 +1,11 @@ +# child_cat.ChildCat + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**pet_type** | **str** | | +**name** | **str** | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/openapi3/client/petstore/python-experimental/docs/ChildCatAllOf.md b/samples/openapi3/client/petstore/python-experimental/docs/ChildCatAllOf.md new file mode 100644 index 00000000000..2e84f31081f --- /dev/null +++ b/samples/openapi3/client/petstore/python-experimental/docs/ChildCatAllOf.md @@ -0,0 +1,10 @@ +# child_cat_all_of.ChildCatAllOf + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**name** | **str** | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/openapi3/client/petstore/python-experimental/docs/BiologyReptile.md b/samples/openapi3/client/petstore/python-experimental/docs/DanishPig.md similarity index 90% rename from samples/openapi3/client/petstore/python-experimental/docs/BiologyReptile.md rename to samples/openapi3/client/petstore/python-experimental/docs/DanishPig.md index 594b477258a..65058d86e04 100644 --- a/samples/openapi3/client/petstore/python-experimental/docs/BiologyReptile.md +++ b/samples/openapi3/client/petstore/python-experimental/docs/DanishPig.md @@ -1,4 +1,4 @@ -# biology_reptile.BiologyReptile +# danish_pig.DanishPig ## Properties Name | Type | Description | Notes diff --git a/samples/openapi3/client/petstore/python-experimental/docs/BiologyChordate.md b/samples/openapi3/client/petstore/python-experimental/docs/GrandparentAnimal.md similarity index 80% rename from samples/openapi3/client/petstore/python-experimental/docs/BiologyChordate.md rename to samples/openapi3/client/petstore/python-experimental/docs/GrandparentAnimal.md index ecccbed7f3c..8a6679f3895 100644 --- a/samples/openapi3/client/petstore/python-experimental/docs/BiologyChordate.md +++ b/samples/openapi3/client/petstore/python-experimental/docs/GrandparentAnimal.md @@ -1,9 +1,9 @@ -# biology_chordate.BiologyChordate +# grandparent_animal.GrandparentAnimal ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**class_name** | **str** | | +**pet_type** | **str** | | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/samples/openapi3/client/petstore/python-experimental/docs/BiologyPrimate.md b/samples/openapi3/client/petstore/python-experimental/docs/ParentPet.md similarity index 81% rename from samples/openapi3/client/petstore/python-experimental/docs/BiologyPrimate.md rename to samples/openapi3/client/petstore/python-experimental/docs/ParentPet.md index 46b91e54a8b..12bfa5c7fe5 100644 --- a/samples/openapi3/client/petstore/python-experimental/docs/BiologyPrimate.md +++ b/samples/openapi3/client/petstore/python-experimental/docs/ParentPet.md @@ -1,9 +1,9 @@ -# biology_primate.BiologyPrimate +# parent_pet.ParentPet ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**class_name** | **str** | | +**pet_type** | **str** | | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/samples/openapi3/client/petstore/python-experimental/docs/BiologyHominid.md b/samples/openapi3/client/petstore/python-experimental/docs/Pig.md similarity index 90% rename from samples/openapi3/client/petstore/python-experimental/docs/BiologyHominid.md rename to samples/openapi3/client/petstore/python-experimental/docs/Pig.md index 408e8c7533a..912ba528011 100644 --- a/samples/openapi3/client/petstore/python-experimental/docs/BiologyHominid.md +++ b/samples/openapi3/client/petstore/python-experimental/docs/Pig.md @@ -1,4 +1,4 @@ -# biology_hominid.BiologyHominid +# pig.Pig ## Properties Name | Type | Description | Notes diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/__init__.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/__init__.py index a24cdd8c3bc..8b945d032fb 100644 --- a/samples/openapi3/client/petstore/python-experimental/petstore_api/__init__.py +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/__init__.py @@ -51,18 +51,17 @@ from petstore_api.models.array_of_number_only import ArrayOfNumberOnly from petstore_api.models.array_test import ArrayTest from petstore_api.models.banana import Banana from petstore_api.models.banana_req import BananaReq -from petstore_api.models.biology_chordate import BiologyChordate -from petstore_api.models.biology_hominid import BiologyHominid -from petstore_api.models.biology_mammal import BiologyMammal -from petstore_api.models.biology_primate import BiologyPrimate -from petstore_api.models.biology_reptile import BiologyReptile +from petstore_api.models.basque_pig import BasquePig from petstore_api.models.capitalization import Capitalization from petstore_api.models.cat import Cat from petstore_api.models.cat_all_of import CatAllOf from petstore_api.models.category import Category +from petstore_api.models.child_cat import ChildCat +from petstore_api.models.child_cat_all_of import ChildCatAllOf from petstore_api.models.class_model import ClassModel from petstore_api.models.client import Client from petstore_api.models.complex_quadrilateral import ComplexQuadrilateral +from petstore_api.models.danish_pig import DanishPig from petstore_api.models.dog import Dog from petstore_api.models.dog_all_of import DogAllOf from petstore_api.models.drawing import Drawing @@ -77,6 +76,7 @@ from petstore_api.models.format_test import FormatTest from petstore_api.models.fruit import Fruit from petstore_api.models.fruit_req import FruitReq from petstore_api.models.gm_fruit import GmFruit +from petstore_api.models.grandparent_animal import GrandparentAnimal from petstore_api.models.has_only_read_only import HasOnlyReadOnly from petstore_api.models.health_check_result import HealthCheckResult from petstore_api.models.inline_object import InlineObject @@ -103,7 +103,9 @@ from petstore_api.models.outer_enum import OuterEnum from petstore_api.models.outer_enum_default_value import OuterEnumDefaultValue from petstore_api.models.outer_enum_integer import OuterEnumInteger from petstore_api.models.outer_enum_integer_default_value import OuterEnumIntegerDefaultValue +from petstore_api.models.parent_pet import ParentPet from petstore_api.models.pet import Pet +from petstore_api.models.pig import Pig from petstore_api.models.quadrilateral import Quadrilateral from petstore_api.models.quadrilateral_interface import QuadrilateralInterface from petstore_api.models.read_only_first import ReadOnlyFirst diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py index 91225e19fcb..1b690f28bdd 100644 --- a/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/model_utils.py @@ -155,26 +155,22 @@ class OpenApiModel(object): cls.discriminator is None or cls in visited_composed_classes ): - # This openapi schema (cls) does not have a discriminator - # Or we have already visited this class before and are sure that we - # want to instantiate it this time. + # Use case 1: this openapi schema (cls) does not have a discriminator + # Use case 2: we have already visited this class before and are sure that we + # want to instantiate it this time. We have visited this class deserializing + # a payload with a discriminator. During that process we traveled through + # this class but did not make an instance of it. Now we are making an + # instance of a composed class which contains cls in it, so this time make an instance of cls. # - # If we are making an instance of a composed schema Descendent - # which allOf includes Ancestor, then Ancestor contains - # a discriminator that includes Descendent. - # So if we make an instance of Descendent, we have to make an - # instance of Ancestor to hold the allOf properties. - # This code detects that use case and makes the instance of Ancestor - # For example: - # When making an instance of Dog, _visited_composed_classes = (Dog,) - # then we make an instance of Animal to include in dog._composed_instances - # so when we are here, cls is Animal - # cls.discriminator != None - # cls not in _visited_composed_classes - # new_cls = Dog - # but we know we know that we already have Dog - # because it is in visited_composed_classes - # so make Animal here + # Here's an example of use case 2: If Animal has a discriminator + # petType and we pass in "Dog", and the class Dog + # allOf includes Animal, we move through Animal + # once using the discriminator, and pick Dog. + # Then in the composed schema dog Dog, we will make an instance of the + # Animal class (because Dal has allOf: Animal) but this time we won't travel + # through Animal's discriminator because we passed in + # _visited_composed_classes = (Animal,) + return super(OpenApiModel, cls).__new__(cls) # Get the name and value of the discriminator property. @@ -213,7 +209,22 @@ class OpenApiModel(object): ) if new_cls in visited_composed_classes: - # if we are coming from the chosen new_cls use cls instead + # if we are making an instance of a composed schema Descendent + # which allOf includes Ancestor, then Ancestor contains + # a discriminator that includes Descendent. + # So if we make an instance of Descendent, we have to make an + # instance of Ancestor to hold the allOf properties. + # This code detects that use case and makes the instance of Ancestor + # For example: + # When making an instance of Dog, _visited_composed_classes = (Dog,) + # then we make an instance of Animal to include in dog._composed_instances + # so when we are here, cls is Animal + # cls.discriminator != None + # cls not in _visited_composed_classes + # new_cls = Dog + # but we know we know that we already have Dog + # because it is in visited_composed_classes + # so make Animal here return super(OpenApiModel, cls).__new__(cls) oneof_anyof_child = new_cls in oneof_anyof_classes @@ -1033,18 +1044,20 @@ def get_discriminator_class(model_class, used_model_class = class_name_to_discr_class.get(discr_value) if used_model_class is None: # We didn't find a discriminated class in class_name_to_discr_class. + # So look in the ancestor or descendant discriminators # The discriminator mapping may exist in a descendant (anyOf, oneOf) # or ancestor (allOf). - # Ancestor example: in the "Dog -> Mammal -> Chordate -> Animal" + # Ancestor example: in the GrandparentAnimal -> ParentPet -> ChildCat # hierarchy, the discriminator mappings may be defined at any level - # in the hieararchy. - # Descendant example: a schema is oneOf[Plant, Mammal], and each - # oneOf child may itself be an allOf with some arbitrary hierarchy, - # and a graph traversal is required to find the discriminator. - composed_children = model_class._composed_schemas.get('oneOf', ()) + \ - model_class._composed_schemas.get('anyOf', ()) + \ - model_class._composed_schemas.get('allOf', ()) - for cls in composed_children: + # in the hierarchy. + # Descendant example: mammal -> whale/zebra/Pig -> BasquePig/DanishPig + # if we try to make BasquePig from mammal, we need to travel through + # the oneOf descendant discriminators to find BasquePig + descendant_classes = model_class._composed_schemas.get('oneOf', ()) + \ + model_class._composed_schemas.get('anyOf', ()) + ancestor_classes = model_class._composed_schemas.get('allOf', ()) + possible_classes = descendant_classes + ancestor_classes + for cls in possible_classes: # Check if the schema has inherited discriminators. if hasattr(cls, 'discriminator') and cls.discriminator is not None: used_model_class = get_discriminator_class( diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_chordate.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/basque_pig.py similarity index 84% rename from samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_chordate.py rename to samples/openapi3/client/petstore/python-experimental/petstore_api/models/basque_pig.py index 3492f4bd3e7..dce1948aacb 100644 --- a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_chordate.py +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/basque_pig.py @@ -32,29 +32,9 @@ from petstore_api.model_utils import ( # noqa: F401 str, validate_get_composed_info, ) -try: - from petstore_api.models import biology_hominid -except ImportError: - biology_hominid = sys.modules[ - 'petstore_api.models.biology_hominid'] -try: - from petstore_api.models import biology_mammal -except ImportError: - biology_mammal = sys.modules[ - 'petstore_api.models.biology_mammal'] -try: - from petstore_api.models import biology_primate -except ImportError: - biology_primate = sys.modules[ - 'petstore_api.models.biology_primate'] -try: - from petstore_api.models import biology_reptile -except ImportError: - biology_reptile = sys.modules[ - 'petstore_api.models.biology_reptile'] -class BiologyChordate(ModelNormal): +class BasquePig(ModelNormal): """NOTE: This class is auto generated by OpenAPI Generator. Ref: https://openapi-generator.tech @@ -102,15 +82,7 @@ class BiologyChordate(ModelNormal): @cached_property def discriminator(): - val = { - 'biology.Hominid': biology_hominid.BiologyHominid, - 'biology.Mammal': biology_mammal.BiologyMammal, - 'biology.Primate': biology_primate.BiologyPrimate, - 'biology.Reptile': biology_reptile.BiologyReptile, - } - if not val: - return None - return {'class_name': val} + return None attribute_map = { 'class_name': 'className', # noqa: E501 @@ -129,7 +101,7 @@ class BiologyChordate(ModelNormal): @convert_js_args_to_python_args def __init__(self, class_name, _check_type=True, _spec_property_naming=False, _path_to_item=(), _configuration=None, _visited_composed_classes=(), **kwargs): # noqa: E501 - """biology_chordate.BiologyChordate - a model defined in OpenAPI + """basque_pig.BasquePig - a model defined in OpenAPI Args: class_name (str): diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_mammal.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_mammal.py deleted file mode 100644 index 3aedd7f2b2a..00000000000 --- a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_mammal.py +++ /dev/null @@ -1,224 +0,0 @@ -# coding: utf-8 - -""" - OpenAPI Petstore - - This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 - - The version of the OpenAPI document: 1.0.0 - Generated by: https://openapi-generator.tech -""" - - -from __future__ import absolute_import -import re # noqa: F401 -import sys # noqa: F401 - -import six # noqa: F401 -import nulltype # noqa: F401 - -from petstore_api.model_utils import ( # noqa: F401 - ModelComposed, - ModelNormal, - ModelSimple, - cached_property, - change_keys_js_to_python, - convert_js_args_to_python_args, - date, - datetime, - file_type, - int, - none_type, - str, - validate_get_composed_info, -) -try: - from petstore_api.models import biology_chordate -except ImportError: - biology_chordate = sys.modules[ - 'petstore_api.models.biology_chordate'] -try: - from petstore_api.models import biology_hominid -except ImportError: - biology_hominid = sys.modules[ - 'petstore_api.models.biology_hominid'] -try: - from petstore_api.models import biology_primate -except ImportError: - biology_primate = sys.modules[ - 'petstore_api.models.biology_primate'] - - -class BiologyMammal(ModelComposed): - """NOTE: This class is auto generated by OpenAPI Generator. - Ref: https://openapi-generator.tech - - Do not edit the class manually. - - Attributes: - allowed_values (dict): The key is the tuple path to the attribute - and the for var_name this is (var_name,). The value is a dict - with a capitalized key describing the allowed value and an allowed - value. These dicts store the allowed enum values. - attribute_map (dict): The key is attribute name - and the value is json key in definition. - discriminator_value_class_map (dict): A dict to go from the discriminator - variable value to the discriminator class name. - validations (dict): The key is the tuple path to the attribute - and the for var_name this is (var_name,). The value is a dict - that stores validations for max_length, min_length, max_items, - min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, - inclusive_minimum, and regex. - additional_properties_type (tuple): A tuple of classes accepted - as additional properties values. - """ - - allowed_values = { - } - - validations = { - } - - additional_properties_type = None - - @cached_property - def openapi_types(): - """ - This must be a class method so a model may have properties that are - of type self, this ensures that we don't create a cyclic import - - Returns - openapi_types (dict): The key is attribute name - and the value is attribute type. - """ - return { - 'class_name': (str,), # noqa: E501 - } - - @cached_property - def discriminator(): - val = { - 'biology.Hominid': biology_hominid.BiologyHominid, - 'biology.Primate': biology_primate.BiologyPrimate, - } - if not val: - return None - return {'class_name': val} - - attribute_map = { - 'class_name': 'className', # noqa: E501 - } - - required_properties = set([ - '_data_store', - '_check_type', - '_spec_property_naming', - '_path_to_item', - '_configuration', - '_visited_composed_classes', - '_composed_instances', - '_var_name_to_model_instances', - '_additional_properties_model_instances', - ]) - - @convert_js_args_to_python_args - def __init__(self, class_name, _check_type=True, _spec_property_naming=False, _path_to_item=(), _configuration=None, _visited_composed_classes=(), **kwargs): # noqa: E501 - """biology_mammal.BiologyMammal - a model defined in OpenAPI - - Args: - class_name (str): - - Keyword Args: - _check_type (bool): if True, values for parameters in openapi_types - will be type checked and a TypeError will be - raised if the wrong type is input. - Defaults to True - _path_to_item (tuple/list): This is a list of keys or values to - drill down to the model in received_data - when deserializing a response - _spec_property_naming (bool): True if the variable names in the input data - are serialized names, as specified in the OpenAPI document. - False if the variable names in the input data - are pythonic names, e.g. snake case (default) - _configuration (Configuration): the instance to use when - deserializing a file_type parameter. - If passed, type conversion is attempted - If omitted no type conversion is done. - _visited_composed_classes (tuple): This stores a tuple of - classes that we have traveled through so that - if we see that class again we will not use its - discriminator again. - When traveling through a discriminator, the - composed schema that is - is traveled through is added to this set. - For example if Animal has a discriminator - petType and we pass in "Dog", and the class Dog - allOf includes Animal, we move through Animal - once using the discriminator, and pick Dog. - Then in Dog, we will make an instance of the - Animal class but this time we won't travel - through its discriminator because we passed in - _visited_composed_classes = (Animal,) - """ - - self._data_store = {} - self._check_type = _check_type - self._spec_property_naming = _spec_property_naming - self._path_to_item = _path_to_item - self._configuration = _configuration - self._visited_composed_classes = _visited_composed_classes + (self.__class__,) - - constant_args = { - '_check_type': _check_type, - '_path_to_item': _path_to_item, - '_spec_property_naming': _spec_property_naming, - '_configuration': _configuration, - '_visited_composed_classes': self._visited_composed_classes, - } - required_args = { - 'class_name': class_name, - } - # remove args whose value is Null because they are unset - required_arg_names = list(required_args.keys()) - for required_arg_name in required_arg_names: - if required_args[required_arg_name] is nulltype.Null: - del required_args[required_arg_name] - model_args = {} - model_args.update(required_args) - model_args.update(kwargs) - composed_info = validate_get_composed_info( - constant_args, model_args, self) - self._composed_instances = composed_info[0] - self._var_name_to_model_instances = composed_info[1] - self._additional_properties_model_instances = composed_info[2] - unused_args = composed_info[3] - - for var_name, var_value in required_args.items(): - setattr(self, var_name, var_value) - for var_name, var_value in six.iteritems(kwargs): - if var_name in unused_args and \ - self._configuration is not None and \ - self._configuration.discard_unknown_keys and \ - not self._additional_properties_model_instances: - # discard variable. - continue - setattr(self, var_name, var_value) - - @cached_property - def _composed_schemas(): - # we need this here to make our import statements work - # we must store _composed_schemas in here so the code is only run - # when we invoke this method. If we kept this at the class - # level we would get an error beause the class level - # code would be run when this module is imported, and these composed - # classes don't exist yet because their module has not finished - # loading - return { - 'anyOf': [ - ], - 'allOf': [ - biology_chordate.BiologyChordate, - ], - 'oneOf': [ - ], - } diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_hominid.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/child_cat.py similarity index 89% rename from samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_hominid.py rename to samples/openapi3/client/petstore/python-experimental/petstore_api/models/child_cat.py index 2ef3b012f7f..3d79c435841 100644 --- a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_hominid.py +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/child_cat.py @@ -33,13 +33,18 @@ from petstore_api.model_utils import ( # noqa: F401 validate_get_composed_info, ) try: - from petstore_api.models import biology_primate + from petstore_api.models import child_cat_all_of except ImportError: - biology_primate = sys.modules[ - 'petstore_api.models.biology_primate'] + child_cat_all_of = sys.modules[ + 'petstore_api.models.child_cat_all_of'] +try: + from petstore_api.models import parent_pet +except ImportError: + parent_pet = sys.modules[ + 'petstore_api.models.parent_pet'] -class BiologyHominid(ModelComposed): +class ChildCat(ModelComposed): """NOTE: This class is auto generated by OpenAPI Generator. Ref: https://openapi-generator.tech @@ -82,7 +87,8 @@ class BiologyHominid(ModelComposed): and the value is attribute type. """ return { - 'class_name': (str,), # noqa: E501 + 'pet_type': (str,), # noqa: E501 + 'name': (str,), # noqa: E501 } @cached_property @@ -91,10 +97,11 @@ class BiologyHominid(ModelComposed): } if not val: return None - return {'class_name': val} + return {'pet_type': val} attribute_map = { - 'class_name': 'className', # noqa: E501 + 'pet_type': 'pet_type', # noqa: E501 + 'name': 'name', # noqa: E501 } required_properties = set([ @@ -110,11 +117,11 @@ class BiologyHominid(ModelComposed): ]) @convert_js_args_to_python_args - def __init__(self, class_name, _check_type=True, _spec_property_naming=False, _path_to_item=(), _configuration=None, _visited_composed_classes=(), **kwargs): # noqa: E501 - """biology_hominid.BiologyHominid - a model defined in OpenAPI + def __init__(self, pet_type, _check_type=True, _spec_property_naming=False, _path_to_item=(), _configuration=None, _visited_composed_classes=(), **kwargs): # noqa: E501 + """child_cat.ChildCat - a model defined in OpenAPI Args: - class_name (str): + pet_type (str): Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -147,6 +154,7 @@ class BiologyHominid(ModelComposed): Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) + name (str): [optional] # noqa: E501 """ self._data_store = {} @@ -164,7 +172,7 @@ class BiologyHominid(ModelComposed): '_visited_composed_classes': self._visited_composed_classes, } required_args = { - 'class_name': class_name, + 'pet_type': pet_type, } # remove args whose value is Null because they are unset required_arg_names = list(required_args.keys()) @@ -205,7 +213,8 @@ class BiologyHominid(ModelComposed): 'anyOf': [ ], 'allOf': [ - biology_primate.BiologyPrimate, + child_cat_all_of.ChildCatAllOf, + parent_pet.ParentPet, ], 'oneOf': [ ], diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/child_cat_all_of.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/child_cat_all_of.py new file mode 100644 index 00000000000..f159c32fd86 --- /dev/null +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/child_cat_all_of.py @@ -0,0 +1,154 @@ +# coding: utf-8 + +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import +import re # noqa: F401 +import sys # noqa: F401 + +import six # noqa: F401 +import nulltype # noqa: F401 + +from petstore_api.model_utils import ( # noqa: F401 + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + int, + none_type, + str, + validate_get_composed_info, +) + + +class ChildCatAllOf(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + } + + validations = { + } + + additional_properties_type = None + + @cached_property + def openapi_types(): + """ + This must be a class method so a model may have properties that are + of type self, this ensures that we don't create a cyclic import + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + 'name': (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + attribute_map = { + 'name': 'name', # noqa: E501 + } + + _composed_schemas = {} + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, _check_type=True, _spec_property_naming=False, _path_to_item=(), _configuration=None, _visited_composed_classes=(), **kwargs): # noqa: E501 + """child_cat_all_of.ChildCatAllOf - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + name (str): [optional] # noqa: E501 + """ + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + for var_name, var_value in six.iteritems(kwargs): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/danish_pig.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/danish_pig.py new file mode 100644 index 00000000000..e1942b69a93 --- /dev/null +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/danish_pig.py @@ -0,0 +1,157 @@ +# coding: utf-8 + +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import +import re # noqa: F401 +import sys # noqa: F401 + +import six # noqa: F401 +import nulltype # noqa: F401 + +from petstore_api.model_utils import ( # noqa: F401 + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + int, + none_type, + str, + validate_get_composed_info, +) + + +class DanishPig(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + } + + validations = { + } + + additional_properties_type = None + + @cached_property + def openapi_types(): + """ + This must be a class method so a model may have properties that are + of type self, this ensures that we don't create a cyclic import + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + 'class_name': (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + attribute_map = { + 'class_name': 'className', # noqa: E501 + } + + _composed_schemas = {} + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, class_name, _check_type=True, _spec_property_naming=False, _path_to_item=(), _configuration=None, _visited_composed_classes=(), **kwargs): # noqa: E501 + """danish_pig.DanishPig - a model defined in OpenAPI + + Args: + class_name (str): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.class_name = class_name + for var_name, var_value in six.iteritems(kwargs): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/grandparent_animal.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/grandparent_animal.py new file mode 100644 index 00000000000..0dc6dd7d74a --- /dev/null +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/grandparent_animal.py @@ -0,0 +1,173 @@ +# coding: utf-8 + +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import +import re # noqa: F401 +import sys # noqa: F401 + +import six # noqa: F401 +import nulltype # noqa: F401 + +from petstore_api.model_utils import ( # noqa: F401 + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + int, + none_type, + str, + validate_get_composed_info, +) +try: + from petstore_api.models import child_cat +except ImportError: + child_cat = sys.modules[ + 'petstore_api.models.child_cat'] +try: + from petstore_api.models import parent_pet +except ImportError: + parent_pet = sys.modules[ + 'petstore_api.models.parent_pet'] + + +class GrandparentAnimal(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + } + + validations = { + } + + additional_properties_type = None + + @cached_property + def openapi_types(): + """ + This must be a class method so a model may have properties that are + of type self, this ensures that we don't create a cyclic import + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + 'pet_type': (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + val = { + 'ChildCat': child_cat.ChildCat, + 'ParentPet': parent_pet.ParentPet, + } + if not val: + return None + return {'pet_type': val} + + attribute_map = { + 'pet_type': 'pet_type', # noqa: E501 + } + + _composed_schemas = {} + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, pet_type, _check_type=True, _spec_property_naming=False, _path_to_item=(), _configuration=None, _visited_composed_classes=(), **kwargs): # noqa: E501 + """grandparent_animal.GrandparentAnimal - a model defined in OpenAPI + + Args: + pet_type (str): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.pet_type = pet_type + for var_name, var_value in six.iteritems(kwargs): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/mammal.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/mammal.py index b0e681737a9..0d354fcd4de 100644 --- a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/mammal.py +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/mammal.py @@ -32,6 +32,11 @@ from petstore_api.model_utils import ( # noqa: F401 str, validate_get_composed_info, ) +try: + from petstore_api.models import pig +except ImportError: + pig = sys.modules[ + 'petstore_api.models.pig'] try: from petstore_api.models import whale except ImportError: @@ -101,6 +106,7 @@ class Mammal(ModelComposed): @cached_property def discriminator(): val = { + 'Pig': pig.Pig, 'whale': whale.Whale, 'zebra': zebra.Zebra, } @@ -228,6 +234,7 @@ class Mammal(ModelComposed): 'allOf': [ ], 'oneOf': [ + pig.Pig, whale.Whale, zebra.Zebra, ], diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_reptile.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/parent_pet.py similarity index 90% rename from samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_reptile.py rename to samples/openapi3/client/petstore/python-experimental/petstore_api/models/parent_pet.py index 0dafde08409..b06e10c4ddc 100644 --- a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_reptile.py +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/parent_pet.py @@ -33,13 +33,18 @@ from petstore_api.model_utils import ( # noqa: F401 validate_get_composed_info, ) try: - from petstore_api.models import biology_chordate + from petstore_api.models import child_cat except ImportError: - biology_chordate = sys.modules[ - 'petstore_api.models.biology_chordate'] + child_cat = sys.modules[ + 'petstore_api.models.child_cat'] +try: + from petstore_api.models import grandparent_animal +except ImportError: + grandparent_animal = sys.modules[ + 'petstore_api.models.grandparent_animal'] -class BiologyReptile(ModelComposed): +class ParentPet(ModelComposed): """NOTE: This class is auto generated by OpenAPI Generator. Ref: https://openapi-generator.tech @@ -82,19 +87,20 @@ class BiologyReptile(ModelComposed): and the value is attribute type. """ return { - 'class_name': (str,), # noqa: E501 + 'pet_type': (str,), # noqa: E501 } @cached_property def discriminator(): val = { + 'ChildCat': child_cat.ChildCat, } if not val: return None - return {'class_name': val} + return {'pet_type': val} attribute_map = { - 'class_name': 'className', # noqa: E501 + 'pet_type': 'pet_type', # noqa: E501 } required_properties = set([ @@ -110,11 +116,11 @@ class BiologyReptile(ModelComposed): ]) @convert_js_args_to_python_args - def __init__(self, class_name, _check_type=True, _spec_property_naming=False, _path_to_item=(), _configuration=None, _visited_composed_classes=(), **kwargs): # noqa: E501 - """biology_reptile.BiologyReptile - a model defined in OpenAPI + def __init__(self, pet_type, _check_type=True, _spec_property_naming=False, _path_to_item=(), _configuration=None, _visited_composed_classes=(), **kwargs): # noqa: E501 + """parent_pet.ParentPet - a model defined in OpenAPI Args: - class_name (str): + pet_type (str): Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -164,7 +170,7 @@ class BiologyReptile(ModelComposed): '_visited_composed_classes': self._visited_composed_classes, } required_args = { - 'class_name': class_name, + 'pet_type': pet_type, } # remove args whose value is Null because they are unset required_arg_names = list(required_args.keys()) @@ -205,7 +211,7 @@ class BiologyReptile(ModelComposed): 'anyOf': [ ], 'allOf': [ - biology_chordate.BiologyChordate, + grandparent_animal.GrandparentAnimal, ], 'oneOf': [ ], diff --git a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_primate.py b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/pig.py similarity index 94% rename from samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_primate.py rename to samples/openapi3/client/petstore/python-experimental/petstore_api/models/pig.py index b643a3c9001..6b984ab6d9d 100644 --- a/samples/openapi3/client/petstore/python-experimental/petstore_api/models/biology_primate.py +++ b/samples/openapi3/client/petstore/python-experimental/petstore_api/models/pig.py @@ -33,18 +33,18 @@ from petstore_api.model_utils import ( # noqa: F401 validate_get_composed_info, ) try: - from petstore_api.models import biology_hominid + from petstore_api.models import basque_pig except ImportError: - biology_hominid = sys.modules[ - 'petstore_api.models.biology_hominid'] + basque_pig = sys.modules[ + 'petstore_api.models.basque_pig'] try: - from petstore_api.models import biology_mammal + from petstore_api.models import danish_pig except ImportError: - biology_mammal = sys.modules[ - 'petstore_api.models.biology_mammal'] + danish_pig = sys.modules[ + 'petstore_api.models.danish_pig'] -class BiologyPrimate(ModelComposed): +class Pig(ModelComposed): """NOTE: This class is auto generated by OpenAPI Generator. Ref: https://openapi-generator.tech @@ -93,7 +93,8 @@ class BiologyPrimate(ModelComposed): @cached_property def discriminator(): val = { - 'biology.Hominid': biology_hominid.BiologyHominid, + 'BasquePig': basque_pig.BasquePig, + 'DanishPig': danish_pig.DanishPig, } if not val: return None @@ -117,7 +118,7 @@ class BiologyPrimate(ModelComposed): @convert_js_args_to_python_args def __init__(self, class_name, _check_type=True, _spec_property_naming=False, _path_to_item=(), _configuration=None, _visited_composed_classes=(), **kwargs): # noqa: E501 - """biology_primate.BiologyPrimate - a model defined in OpenAPI + """pig.Pig - a model defined in OpenAPI Args: class_name (str): @@ -211,8 +212,9 @@ class BiologyPrimate(ModelComposed): 'anyOf': [ ], 'allOf': [ - biology_mammal.BiologyMammal, ], 'oneOf': [ + basque_pig.BasquePig, + danish_pig.DanishPig, ], } diff --git a/samples/openapi3/client/petstore/python-experimental/test/test_biology_mammal.py b/samples/openapi3/client/petstore/python-experimental/test/test_basque_pig.py similarity index 74% rename from samples/openapi3/client/petstore/python-experimental/test/test_biology_mammal.py rename to samples/openapi3/client/petstore/python-experimental/test/test_basque_pig.py index f894d72ff57..46e9ff215dc 100644 --- a/samples/openapi3/client/petstore/python-experimental/test/test_biology_mammal.py +++ b/samples/openapi3/client/petstore/python-experimental/test/test_basque_pig.py @@ -17,8 +17,8 @@ import unittest import petstore_api -class TestBiologyMammal(unittest.TestCase): - """BiologyMammal unit test stubs""" +class TestBasquePig(unittest.TestCase): + """BasquePig unit test stubs""" def setUp(self): pass @@ -26,10 +26,10 @@ class TestBiologyMammal(unittest.TestCase): def tearDown(self): pass - def testBiologyMammal(self): - """Test BiologyMammal""" + def testBasquePig(self): + """Test BasquePig""" # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.BiologyMammal() # noqa: E501 + # model = petstore_api.BasquePig() # noqa: E501 pass diff --git a/samples/openapi3/client/petstore/python-experimental/test/test_biology_reptile.py b/samples/openapi3/client/petstore/python-experimental/test/test_child_cat.py similarity index 74% rename from samples/openapi3/client/petstore/python-experimental/test/test_biology_reptile.py rename to samples/openapi3/client/petstore/python-experimental/test/test_child_cat.py index e29f0c9a724..c42c3b583aa 100644 --- a/samples/openapi3/client/petstore/python-experimental/test/test_biology_reptile.py +++ b/samples/openapi3/client/petstore/python-experimental/test/test_child_cat.py @@ -17,8 +17,8 @@ import unittest import petstore_api -class TestBiologyReptile(unittest.TestCase): - """BiologyReptile unit test stubs""" +class TestChildCat(unittest.TestCase): + """ChildCat unit test stubs""" def setUp(self): pass @@ -26,10 +26,10 @@ class TestBiologyReptile(unittest.TestCase): def tearDown(self): pass - def testBiologyReptile(self): - """Test BiologyReptile""" + def testChildCat(self): + """Test ChildCat""" # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.BiologyReptile() # noqa: E501 + # model = petstore_api.ChildCat() # noqa: E501 pass diff --git a/samples/openapi3/client/petstore/python-experimental/test/test_biology_hominid.py b/samples/openapi3/client/petstore/python-experimental/test/test_child_cat_all_of.py similarity index 74% rename from samples/openapi3/client/petstore/python-experimental/test/test_biology_hominid.py rename to samples/openapi3/client/petstore/python-experimental/test/test_child_cat_all_of.py index f50167a4e25..3304a81a232 100644 --- a/samples/openapi3/client/petstore/python-experimental/test/test_biology_hominid.py +++ b/samples/openapi3/client/petstore/python-experimental/test/test_child_cat_all_of.py @@ -17,8 +17,8 @@ import unittest import petstore_api -class TestBiologyHominid(unittest.TestCase): - """BiologyHominid unit test stubs""" +class TestChildCatAllOf(unittest.TestCase): + """ChildCatAllOf unit test stubs""" def setUp(self): pass @@ -26,10 +26,10 @@ class TestBiologyHominid(unittest.TestCase): def tearDown(self): pass - def testBiologyHominid(self): - """Test BiologyHominid""" + def testChildCatAllOf(self): + """Test ChildCatAllOf""" # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.BiologyHominid() # noqa: E501 + # model = petstore_api.ChildCatAllOf() # noqa: E501 pass diff --git a/samples/openapi3/client/petstore/python-experimental/test/test_biology_primate.py b/samples/openapi3/client/petstore/python-experimental/test/test_danish_pig.py similarity index 74% rename from samples/openapi3/client/petstore/python-experimental/test/test_biology_primate.py rename to samples/openapi3/client/petstore/python-experimental/test/test_danish_pig.py index e07b3e11c21..0cbe8f8c102 100644 --- a/samples/openapi3/client/petstore/python-experimental/test/test_biology_primate.py +++ b/samples/openapi3/client/petstore/python-experimental/test/test_danish_pig.py @@ -17,8 +17,8 @@ import unittest import petstore_api -class TestBiologyPrimate(unittest.TestCase): - """BiologyPrimate unit test stubs""" +class TestDanishPig(unittest.TestCase): + """DanishPig unit test stubs""" def setUp(self): pass @@ -26,10 +26,10 @@ class TestBiologyPrimate(unittest.TestCase): def tearDown(self): pass - def testBiologyPrimate(self): - """Test BiologyPrimate""" + def testDanishPig(self): + """Test DanishPig""" # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.BiologyPrimate() # noqa: E501 + # model = petstore_api.DanishPig() # noqa: E501 pass diff --git a/samples/openapi3/client/petstore/python-experimental/test/test_biology_chordate.py b/samples/openapi3/client/petstore/python-experimental/test/test_grandparent_animal.py similarity index 72% rename from samples/openapi3/client/petstore/python-experimental/test/test_biology_chordate.py rename to samples/openapi3/client/petstore/python-experimental/test/test_grandparent_animal.py index 3839589b9c5..dc0d300cdae 100644 --- a/samples/openapi3/client/petstore/python-experimental/test/test_biology_chordate.py +++ b/samples/openapi3/client/petstore/python-experimental/test/test_grandparent_animal.py @@ -17,8 +17,8 @@ import unittest import petstore_api -class TestBiologyChordate(unittest.TestCase): - """BiologyChordate unit test stubs""" +class TestGrandparentAnimal(unittest.TestCase): + """GrandparentAnimal unit test stubs""" def setUp(self): pass @@ -26,10 +26,10 @@ class TestBiologyChordate(unittest.TestCase): def tearDown(self): pass - def testBiologyChordate(self): - """Test BiologyChordate""" + def testGrandparentAnimal(self): + """Test GrandparentAnimal""" # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.BiologyChordate() # noqa: E501 + # model = petstore_api.GrandparentAnimal() # noqa: E501 pass diff --git a/samples/openapi3/client/petstore/python-experimental/test/test_mammal.py b/samples/openapi3/client/petstore/python-experimental/test/test_mammal.py index 1b4f161196e..cc783f53ed6 100644 --- a/samples/openapi3/client/petstore/python-experimental/test/test_mammal.py +++ b/samples/openapi3/client/petstore/python-experimental/test/test_mammal.py @@ -28,9 +28,10 @@ class TestMammal(unittest.TestCase): def testMammal(self): """Test Mammal""" - # FIXME: construct object with mandatory attributes with example values - # model = petstore_api.Mammal() # noqa: E501 - pass + + # tests that we can make a BasquePig by traveling through descendant discriminator in Pig + model = petstore_api.Mammal(class_name="BasquePig") + assert isinstance(model, petstore_api.BasquePig) if __name__ == '__main__': diff --git a/samples/openapi3/client/petstore/python-experimental/test/test_parent_pet.py b/samples/openapi3/client/petstore/python-experimental/test/test_parent_pet.py new file mode 100644 index 00000000000..8db04124d66 --- /dev/null +++ b/samples/openapi3/client/petstore/python-experimental/test/test_parent_pet.py @@ -0,0 +1,39 @@ +# coding: utf-8 + +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +import unittest + +import petstore_api + + +class TestParentPet(unittest.TestCase): + """ParentPet unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testParentPet(self): + """Test ParentPet""" + + # test that we can make a ParentPet from a ParentPet + # which requires that we travel back through ParentPet's allOf descendant + # GrandparentAnimal, and we use the descendant's discriminator to make ParentPet + model = petstore_api.ParentPet(pet_type="ParentPet") + assert isinstance(model, petstore_api.ParentPet) + +if __name__ == '__main__': + unittest.main() diff --git a/samples/openapi3/client/petstore/python-experimental/test/test_pig.py b/samples/openapi3/client/petstore/python-experimental/test/test_pig.py new file mode 100644 index 00000000000..afdd210da7d --- /dev/null +++ b/samples/openapi3/client/petstore/python-experimental/test/test_pig.py @@ -0,0 +1,37 @@ +# coding: utf-8 + +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +import unittest + +import petstore_api + + +class TestPig(unittest.TestCase): + """Pig unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testPig(self): + """Test Pig""" + # FIXME: construct object with mandatory attributes with example values + # model = petstore_api.Pig() # noqa: E501 + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/samples/openapi3/client/petstore/python-experimental/tests/test_chordates.py b/samples/openapi3/client/petstore/python-experimental/tests/test_chordates.py deleted file mode 100644 index 8ebb8c2cdd1..00000000000 --- a/samples/openapi3/client/petstore/python-experimental/tests/test_chordates.py +++ /dev/null @@ -1,67 +0,0 @@ -# coding: utf-8 - -""" -Run the tests. -$ pip install nose (optional) -$ cd OpenAPIPetstore-python -$ nosetests -v -""" - - -from __future__ import absolute_import - -import unittest - -import petstore_api - - -class TestChordates(unittest.TestCase): - - def setUp(self): - pass - - def tearDown(self): - pass - - def testChordateDeserializationAndDiscriminator(self): - """Test Chordates deserialization - It should be possible to create instances from anywhere - in the animal class hierarchy, as long as the discriminator - value is valid. Internally, the get_discriminator_class() - function may need to call itself recursively to traverse - the composed hierarchy. - These unit tests would not work if get_discriminator_class - did not call itself recursively. - """ - inst = petstore_api.BiologyChordate( - class_name="biology.Mammal", - ) - assert isinstance(inst, petstore_api.BiologyMammal) - - inst = petstore_api.BiologyChordate( - class_name="biology.Primate", - ) - assert isinstance(inst, petstore_api.BiologyPrimate) - - inst = petstore_api.BiologyChordate( - class_name="biology.Reptile", - ) - assert isinstance(inst, petstore_api.BiologyReptile) - - inst = petstore_api.BiologyChordate( - class_name="biology.Hominid", - ) - assert isinstance(inst, petstore_api.BiologyHominid) - - def testMammalDeserializationAndDiscriminator(self): - """Test Chordates deserialization""" - inst = petstore_api.BiologyMammal( - class_name="biology.Hominid", - ) - assert isinstance(inst, petstore_api.BiologyHominid) - - def testHominidDeserializationAndDiscriminator(self): - inst = petstore_api.BiologyHominid( - class_name="biology.Hominid", - ) - assert isinstance(inst, petstore_api.BiologyHominid)