From f7106f1cd2acfe00463cb2a7549d6f05fd866da4 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Fri, 18 Nov 2022 11:03:14 -0800 Subject: [PATCH 1/6] Adds and uses add_deeper_validated_schemas --- .../main/resources/python/schemas.handlebars | 13 +++++++++ .../petstore/python/petstore_api/schemas.py | 28 +++++++++++++++++++ .../petstore/python/tests_manual/test_pet.py | 28 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 samples/openapi3/client/petstore/python/tests_manual/test_pet.py diff --git a/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars b/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars index 22999b13062..1848f73cbb5 100644 --- a/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars +++ b/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars @@ -141,6 +141,19 @@ class ValidationMetadata(frozendict.frozendict): return self.get('validated_path_to_schemas') +def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_to_schemas: dict): + # this is called if validation_ran_earlier and deeper loactions need to be added + current_path_to_item = validation_metadata.path_to_item + other_path_to_schemas = {} + for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items(): + if len(path_to_item) <= current_path_to_item: + continue + path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item + if path_begins_with_current_path: + other_path_to_schemas[path_to_item] = schemas + update(path_to_schemas, other_path_to_schemas) + + class Singleton: """ Enums and singletons are the same diff --git a/samples/openapi3/client/petstore/python/petstore_api/schemas.py b/samples/openapi3/client/petstore/python/petstore_api/schemas.py index e2c6c665dd8..05d266ba550 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/schemas.py +++ b/samples/openapi3/client/petstore/python/petstore_api/schemas.py @@ -148,6 +148,19 @@ def validated_path_to_schemas(self) -> typing.Dict[typing.Tuple[typing.Union[str return self.get('validated_path_to_schemas') +def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_to_schemas: dict): + # this is called if validation_ran_earlier and deeper loactions need to be added + current_path_to_item = validation_metadata.path_to_item + other_path_to_schemas = {} + for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items(): + if len(path_to_item) <= current_path_to_item: + continue + path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item + if path_begins_with_current_path: + other_path_to_schemas[path_to_item] = schemas + update(path_to_schemas, other_path_to_schemas) + + class Singleton: """ Enums and singletons are the same @@ -399,6 +412,7 @@ def __get_new_cls( update(_path_to_schemas, other_path_to_schemas) # loop through it make a new class for each entry # do not modify the returned result because it is cached and we would be modifying the cached value + print(f'_path_to_schemas {_path_to_schemas}') path_to_schemas = {} for path, schema_classes in _path_to_schemas.items(): """ @@ -1332,6 +1346,7 @@ def __validate_items(cls, list_items, validation_metadata: ValidationMetadata): validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if item_validation_metadata.validation_ran_earlier(item_cls): + add_deeper_validated_schemas(item_validation_metadata, path_to_schemas) continue other_path_to_schemas = item_cls._validate_oapg( value, validation_metadata=item_validation_metadata) @@ -1595,6 +1610,7 @@ def __validate_args(cls, arg, validation_metadata: ValidationMetadata): validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if arg_validation_metadata.validation_ran_earlier(schema): + add_deeper_validated_schemas(arg_validation_metadata, path_to_schemas) continue other_path_to_schemas = schema._validate_oapg(value, validation_metadata=arg_validation_metadata) update(path_to_schemas, other_path_to_schemas) @@ -1649,6 +1665,8 @@ def _validate_oapg( ApiValueError: when a string can't be converted into a date or datetime and it must be one of those classes ApiTypeError: when the input type is not in the list of allowed spec types """ + import pdb + pdb.set_trace() if isinstance(arg, frozendict.frozendict): cls.__check_dict_validations(arg, validation_metadata) _path_to_schemas = super()._validate_oapg(arg, validation_metadata=validation_metadata) @@ -1683,6 +1701,7 @@ def _validate_oapg( validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if updated_vm.validation_ran_earlier(discriminated_cls): + add_deeper_validated_schemas(updated_vm, _path_to_schemas) return _path_to_schemas other_path_to_schemas = discriminated_cls._validate_oapg(arg, validation_metadata=updated_vm) update(_path_to_schemas, other_path_to_schemas) @@ -1704,6 +1723,11 @@ def _get_properties_oapg( for property_name_js, value in arg.items(): property_path_to_item = path_to_item + (property_name_js,) property_cls = path_to_schemas[property_path_to_item] + print(f'property_name_js {property_name_js}') + print(f'value {value}') + print(f'property_cls {property_cls}') + print(f'property_cls.__bases__ {property_cls.__bases__}') + print(f'property_path_to_item {property_path_to_item}') new_value = property_cls._get_new_instance_without_conversion_oapg( value, property_path_to_item, @@ -1845,6 +1869,7 @@ def __get_allof_classes(cls, arg, validation_metadata: ValidationMetadata): path_to_schemas = defaultdict(set) for allof_cls in cls.MetaOapg.all_of(): if validation_metadata.validation_ran_earlier(allof_cls): + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue other_path_to_schemas = allof_cls._validate_oapg(arg, validation_metadata=validation_metadata) update(path_to_schemas, other_path_to_schemas) @@ -1865,6 +1890,7 @@ def __get_oneof_class( continue if validation_metadata.validation_ran_earlier(oneof_cls): oneof_classes.append(oneof_cls) + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue try: path_to_schemas = oneof_cls._validate_oapg(arg, validation_metadata=validation_metadata) @@ -1898,6 +1924,7 @@ def __get_anyof_classes( for anyof_cls in cls.MetaOapg.any_of(): if validation_metadata.validation_ran_earlier(anyof_cls): anyof_classes.append(anyof_cls) + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue try: @@ -2011,6 +2038,7 @@ def _validate_oapg( if discriminated_cls is not None and not updated_vm.validation_ran_earlier(discriminated_cls): # TODO use an exception from this package here + add_deeper_validated_schemas(updated_vm, path_to_schemas) assert discriminated_cls in path_to_schemas[updated_vm.path_to_item] return path_to_schemas diff --git a/samples/openapi3/client/petstore/python/tests_manual/test_pet.py b/samples/openapi3/client/petstore/python/tests_manual/test_pet.py new file mode 100644 index 00000000000..80a13f73ea8 --- /dev/null +++ b/samples/openapi3/client/petstore/python/tests_manual/test_pet.py @@ -0,0 +1,28 @@ +# 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 +""" + + +import unittest + +from petstore_api.model import pet +from petstore_api.model import category + + +class TesttPet(unittest.TestCase): + """ParentPet unit test stubs""" + + def testPet(self): + cat = category.Category(name='hi', addprop={'a': 1}) + _inst = pet.Pet(photoUrls=[], name='Katsu', category=cat) + + +if __name__ == '__main__': + unittest.main() From ab53133cc80709e93ae553d0849cf72e75ab46d4 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Fri, 18 Nov 2022 11:10:59 -0800 Subject: [PATCH 2/6] Adds fix --- .../petstore/python/petstore_api/schemas.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/samples/openapi3/client/petstore/python/petstore_api/schemas.py b/samples/openapi3/client/petstore/python/petstore_api/schemas.py index 05d266ba550..aea569a0424 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/schemas.py +++ b/samples/openapi3/client/petstore/python/petstore_api/schemas.py @@ -153,7 +153,7 @@ def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_t current_path_to_item = validation_metadata.path_to_item other_path_to_schemas = {} for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items(): - if len(path_to_item) <= current_path_to_item: + if len(path_to_item) <= len(current_path_to_item): continue path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item if path_begins_with_current_path: @@ -1805,18 +1805,11 @@ def cast_to_allowed_types( if isinstance(arg, Schema): # store the already run validations schema_classes = set() - source_schema_was_unset = len(arg.__class__.__bases__) == 2 and UnsetAnyTypeSchema in arg.__class__.__bases__ - if not source_schema_was_unset: - """ - Do not include UnsetAnyTypeSchema and its base class because - it did not exist in the original spec schema definition - It was added to ensure that all instances are of type Schema and the allowed base types - """ - for cls in arg.__class__.__bases__: - if cls is Singleton: - # Skip Singleton - continue - schema_classes.add(cls) + for cls in arg.__class__.__bases__: + if cls is Singleton: + # Skip Singleton + continue + schema_classes.add(cls) validated_path_to_schemas[path_to_item] = schema_classes type_error = ApiTypeError(f"Invalid type. Required value type is str and passed type was {type(arg)} at {path_to_item}") From b2fb01afd4c51ff939c952fd0460a6acbdc54a6f Mon Sep 17 00:00:00 2001 From: Justin Black Date: Fri, 18 Nov 2022 13:13:33 -0800 Subject: [PATCH 3/6] Template updated with fix and pestore sample regenerated --- .../main/resources/python/schemas.handlebars | 24 +++++++++---------- .../python/.openapi-generator/VERSION | 2 +- .../petstore/python/petstore_api/schemas.py | 10 +------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars b/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars index 1848f73cbb5..e971aae81b1 100644 --- a/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars +++ b/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars @@ -1338,6 +1338,7 @@ class ListBase(ValidatorBase): validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if item_validation_metadata.validation_ran_earlier(item_cls): + add_deeper_validated_schemas(item_validation_metadata, path_to_schemas) continue other_path_to_schemas = item_cls._validate_oapg( value, validation_metadata=item_validation_metadata) @@ -1601,6 +1602,7 @@ class DictBase(Discriminable, ValidatorBase): validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if arg_validation_metadata.validation_ran_earlier(schema): + add_deeper_validated_schemas(arg_validation_metadata, path_to_schemas) continue other_path_to_schemas = schema._validate_oapg(value, validation_metadata=arg_validation_metadata) update(path_to_schemas, other_path_to_schemas) @@ -1689,6 +1691,7 @@ class DictBase(Discriminable, ValidatorBase): validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if updated_vm.validation_ran_earlier(discriminated_cls): + add_deeper_validated_schemas(updated_vm, _path_to_schemas) return _path_to_schemas other_path_to_schemas = discriminated_cls._validate_oapg(arg, validation_metadata=updated_vm) update(_path_to_schemas, other_path_to_schemas) @@ -1787,18 +1790,11 @@ def cast_to_allowed_types( if isinstance(arg, Schema): # store the already run validations schema_classes = set() - source_schema_was_unset = len(arg.__class__.__bases__) == 2 and UnsetAnyTypeSchema in arg.__class__.__bases__ - if not source_schema_was_unset: - """ - Do not include UnsetAnyTypeSchema and its base class because - it did not exist in the original spec schema definition - It was added to ensure that all instances are of type Schema and the allowed base types - """ - for cls in arg.__class__.__bases__: - if cls is Singleton: - # Skip Singleton - continue - schema_classes.add(cls) + for cls in arg.__class__.__bases__: + if cls is Singleton: + # Skip Singleton + continue + schema_classes.add(cls) validated_path_to_schemas[path_to_item] = schema_classes type_error = ApiTypeError(f"Invalid type. Required value type is str and passed type was {type(arg)} at {path_to_item}") @@ -1851,6 +1847,7 @@ class ComposedBase(Discriminable): path_to_schemas = defaultdict(set) for allof_cls in cls.MetaOapg.all_of(): if validation_metadata.validation_ran_earlier(allof_cls): + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue other_path_to_schemas = allof_cls._validate_oapg(arg, validation_metadata=validation_metadata) update(path_to_schemas, other_path_to_schemas) @@ -1871,6 +1868,7 @@ class ComposedBase(Discriminable): continue if validation_metadata.validation_ran_earlier(oneof_cls): oneof_classes.append(oneof_cls) + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue try: path_to_schemas = oneof_cls._validate_oapg(arg, validation_metadata=validation_metadata) @@ -1928,6 +1926,7 @@ class ComposedBase(Discriminable): for anyof_cls in cls.MetaOapg.any_of(): if validation_metadata.validation_ran_earlier(anyof_cls): anyof_classes.append(anyof_cls) + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue try: @@ -2057,6 +2056,7 @@ class ComposedBase(Discriminable): if discriminated_cls is not None and not updated_vm.validation_ran_earlier(discriminated_cls): # TODO use an exception from this package here + add_deeper_validated_schemas(updated_vm, path_to_schemas) assert discriminated_cls in path_to_schemas[updated_vm.path_to_item] return path_to_schemas diff --git a/samples/openapi3/client/petstore/python/.openapi-generator/VERSION b/samples/openapi3/client/petstore/python/.openapi-generator/VERSION index e4c0d46e55f..717311e32e3 100644 --- a/samples/openapi3/client/petstore/python/.openapi-generator/VERSION +++ b/samples/openapi3/client/petstore/python/.openapi-generator/VERSION @@ -1 +1 @@ -1.0.3 \ No newline at end of file +unset \ No newline at end of file diff --git a/samples/openapi3/client/petstore/python/petstore_api/schemas.py b/samples/openapi3/client/petstore/python/petstore_api/schemas.py index aea569a0424..66c7179b233 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/schemas.py +++ b/samples/openapi3/client/petstore/python/petstore_api/schemas.py @@ -153,7 +153,7 @@ def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_t current_path_to_item = validation_metadata.path_to_item other_path_to_schemas = {} for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items(): - if len(path_to_item) <= len(current_path_to_item): + if len(path_to_item) <= current_path_to_item: continue path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item if path_begins_with_current_path: @@ -412,7 +412,6 @@ def __get_new_cls( update(_path_to_schemas, other_path_to_schemas) # loop through it make a new class for each entry # do not modify the returned result because it is cached and we would be modifying the cached value - print(f'_path_to_schemas {_path_to_schemas}') path_to_schemas = {} for path, schema_classes in _path_to_schemas.items(): """ @@ -1665,8 +1664,6 @@ def _validate_oapg( ApiValueError: when a string can't be converted into a date or datetime and it must be one of those classes ApiTypeError: when the input type is not in the list of allowed spec types """ - import pdb - pdb.set_trace() if isinstance(arg, frozendict.frozendict): cls.__check_dict_validations(arg, validation_metadata) _path_to_schemas = super()._validate_oapg(arg, validation_metadata=validation_metadata) @@ -1723,11 +1720,6 @@ def _get_properties_oapg( for property_name_js, value in arg.items(): property_path_to_item = path_to_item + (property_name_js,) property_cls = path_to_schemas[property_path_to_item] - print(f'property_name_js {property_name_js}') - print(f'value {value}') - print(f'property_cls {property_cls}') - print(f'property_cls.__bases__ {property_cls.__bases__}') - print(f'property_path_to_item {property_path_to_item}') new_value = property_cls._get_new_instance_without_conversion_oapg( value, property_path_to_item, From 0345d41dcef1ead8551a03b1fdf084f5a909f64f Mon Sep 17 00:00:00 2001 From: Justin Black Date: Fri, 18 Nov 2022 13:14:38 -0800 Subject: [PATCH 4/6] Fixes length comparison --- .../src/main/resources/python/schemas.handlebars | 2 +- samples/openapi3/client/petstore/python/petstore_api/schemas.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars b/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars index e971aae81b1..ff1517712f6 100644 --- a/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars +++ b/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars @@ -146,7 +146,7 @@ def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_t current_path_to_item = validation_metadata.path_to_item other_path_to_schemas = {} for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items(): - if len(path_to_item) <= current_path_to_item: + if len(path_to_item) <= len(current_path_to_item): continue path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item if path_begins_with_current_path: diff --git a/samples/openapi3/client/petstore/python/petstore_api/schemas.py b/samples/openapi3/client/petstore/python/petstore_api/schemas.py index 66c7179b233..c43c21f8aad 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/schemas.py +++ b/samples/openapi3/client/petstore/python/petstore_api/schemas.py @@ -153,7 +153,7 @@ def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_t current_path_to_item = validation_metadata.path_to_item other_path_to_schemas = {} for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items(): - if len(path_to_item) <= current_path_to_item: + if len(path_to_item) <= len(current_path_to_item): continue path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item if path_begins_with_current_path: From 7d6202cf92d80bac99ee3c4b8b1a9e344e36f526 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Fri, 18 Nov 2022 13:53:41 -0800 Subject: [PATCH 5/6] Further fix --- .../src/main/resources/python/schemas.handlebars | 10 +++++----- .../petstore/python/petstore_api/schemas.py | 10 +++++----- .../petstore/python/tests_manual/test_pet.py | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars b/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars index ff1517712f6..de79feab8e0 100644 --- a/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars +++ b/modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars @@ -142,11 +142,11 @@ class ValidationMetadata(frozendict.frozendict): def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_to_schemas: dict): - # this is called if validation_ran_earlier and deeper loactions need to be added + # this is called if validation_ran_earlier and current and deeper locations need to be added current_path_to_item = validation_metadata.path_to_item other_path_to_schemas = {} for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items(): - if len(path_to_item) <= len(current_path_to_item): + if len(path_to_item) < len(current_path_to_item): continue path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item if path_begins_with_current_path: @@ -398,9 +398,9 @@ class Schema: because value is of the correct type, and validation was run earlier when the instance was created """ _path_to_schemas = {} - if validation_metadata.validated_path_to_schemas: - update(_path_to_schemas, validation_metadata.validated_path_to_schemas) - if not validation_metadata.validation_ran_earlier(cls): + if validation_metadata.validation_ran_earlier(cls): + add_deeper_validated_schemas(validation_metadata, _path_to_schemas) + else: other_path_to_schemas = cls._validate_oapg(arg, validation_metadata=validation_metadata) update(_path_to_schemas, other_path_to_schemas) # loop through it make a new class for each entry diff --git a/samples/openapi3/client/petstore/python/petstore_api/schemas.py b/samples/openapi3/client/petstore/python/petstore_api/schemas.py index c43c21f8aad..33d6e5b48b3 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/schemas.py +++ b/samples/openapi3/client/petstore/python/petstore_api/schemas.py @@ -149,11 +149,11 @@ def validated_path_to_schemas(self) -> typing.Dict[typing.Tuple[typing.Union[str def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_to_schemas: dict): - # this is called if validation_ran_earlier and deeper loactions need to be added + # this is called if validation_ran_earlier and current and deeper locations need to be added current_path_to_item = validation_metadata.path_to_item other_path_to_schemas = {} for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items(): - if len(path_to_item) <= len(current_path_to_item): + if len(path_to_item) < len(current_path_to_item): continue path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item if path_begins_with_current_path: @@ -405,9 +405,9 @@ def __get_new_cls( because value is of the correct type, and validation was run earlier when the instance was created """ _path_to_schemas = {} - if validation_metadata.validated_path_to_schemas: - update(_path_to_schemas, validation_metadata.validated_path_to_schemas) - if not validation_metadata.validation_ran_earlier(cls): + if validation_metadata.validation_ran_earlier(cls): + add_deeper_validated_schemas(validation_metadata, _path_to_schemas) + else: other_path_to_schemas = cls._validate_oapg(arg, validation_metadata=validation_metadata) update(_path_to_schemas, other_path_to_schemas) # loop through it make a new class for each entry diff --git a/samples/openapi3/client/petstore/python/tests_manual/test_pet.py b/samples/openapi3/client/petstore/python/tests_manual/test_pet.py index 80a13f73ea8..726a85c2d35 100644 --- a/samples/openapi3/client/petstore/python/tests_manual/test_pet.py +++ b/samples/openapi3/client/petstore/python/tests_manual/test_pet.py @@ -9,7 +9,7 @@ Generated by: https://openapi-generator.tech """ - +import decimal import unittest from petstore_api.model import pet @@ -21,7 +21,18 @@ class TesttPet(unittest.TestCase): def testPet(self): cat = category.Category(name='hi', addprop={'a': 1}) - _inst = pet.Pet(photoUrls=[], name='Katsu', category=cat) + inst = pet.Pet(photoUrls=[], name='Katsu', category=cat) + self.assertEqual( + inst, + { + 'photoUrls': (), + 'name': 'Katsu', + 'category': { + 'name': 'hi', + 'addprop': {'a': decimal.Decimal('1')} + } + } + ) if __name__ == '__main__': From 2845e0b005c815af3877361df390ae5182ff2010 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Fri, 18 Nov 2022 14:03:14 -0800 Subject: [PATCH 6/6] Updates samples --- .../python/unit_test_api/schemas.py | 43 ++++++++++++------- .../python/this_package/schemas.py | 43 ++++++++++++------- .../python/.openapi-generator/VERSION | 2 +- 3 files changed, 57 insertions(+), 31 deletions(-) diff --git a/samples/openapi3/client/3_0_3_unit_test/python/unit_test_api/schemas.py b/samples/openapi3/client/3_0_3_unit_test/python/unit_test_api/schemas.py index d6c0284ab19..7e443c6d5e6 100644 --- a/samples/openapi3/client/3_0_3_unit_test/python/unit_test_api/schemas.py +++ b/samples/openapi3/client/3_0_3_unit_test/python/unit_test_api/schemas.py @@ -148,6 +148,19 @@ def validated_path_to_schemas(self) -> typing.Dict[typing.Tuple[typing.Union[str return self.get('validated_path_to_schemas') +def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_to_schemas: dict): + # this is called if validation_ran_earlier and current and deeper locations need to be added + current_path_to_item = validation_metadata.path_to_item + other_path_to_schemas = {} + for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items(): + if len(path_to_item) < len(current_path_to_item): + continue + path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item + if path_begins_with_current_path: + other_path_to_schemas[path_to_item] = schemas + update(path_to_schemas, other_path_to_schemas) + + class Singleton: """ Enums and singletons are the same @@ -392,9 +405,9 @@ def __get_new_cls( because value is of the correct type, and validation was run earlier when the instance was created """ _path_to_schemas = {} - if validation_metadata.validated_path_to_schemas: - update(_path_to_schemas, validation_metadata.validated_path_to_schemas) - if not validation_metadata.validation_ran_earlier(cls): + if validation_metadata.validation_ran_earlier(cls): + add_deeper_validated_schemas(validation_metadata, _path_to_schemas) + else: other_path_to_schemas = cls._validate_oapg(arg, validation_metadata=validation_metadata) update(_path_to_schemas, other_path_to_schemas) # loop through it make a new class for each entry @@ -1332,6 +1345,7 @@ def __validate_items(cls, list_items, validation_metadata: ValidationMetadata): validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if item_validation_metadata.validation_ran_earlier(item_cls): + add_deeper_validated_schemas(item_validation_metadata, path_to_schemas) continue other_path_to_schemas = item_cls._validate_oapg( value, validation_metadata=item_validation_metadata) @@ -1595,6 +1609,7 @@ def __validate_args(cls, arg, validation_metadata: ValidationMetadata): validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if arg_validation_metadata.validation_ran_earlier(schema): + add_deeper_validated_schemas(arg_validation_metadata, path_to_schemas) continue other_path_to_schemas = schema._validate_oapg(value, validation_metadata=arg_validation_metadata) update(path_to_schemas, other_path_to_schemas) @@ -1683,6 +1698,7 @@ def _validate_oapg( validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if updated_vm.validation_ran_earlier(discriminated_cls): + add_deeper_validated_schemas(updated_vm, _path_to_schemas) return _path_to_schemas other_path_to_schemas = discriminated_cls._validate_oapg(arg, validation_metadata=updated_vm) update(_path_to_schemas, other_path_to_schemas) @@ -1781,18 +1797,11 @@ def cast_to_allowed_types( if isinstance(arg, Schema): # store the already run validations schema_classes = set() - source_schema_was_unset = len(arg.__class__.__bases__) == 2 and UnsetAnyTypeSchema in arg.__class__.__bases__ - if not source_schema_was_unset: - """ - Do not include UnsetAnyTypeSchema and its base class because - it did not exist in the original spec schema definition - It was added to ensure that all instances are of type Schema and the allowed base types - """ - for cls in arg.__class__.__bases__: - if cls is Singleton: - # Skip Singleton - continue - schema_classes.add(cls) + for cls in arg.__class__.__bases__: + if cls is Singleton: + # Skip Singleton + continue + schema_classes.add(cls) validated_path_to_schemas[path_to_item] = schema_classes type_error = ApiTypeError(f"Invalid type. Required value type is str and passed type was {type(arg)} at {path_to_item}") @@ -1845,6 +1854,7 @@ def __get_allof_classes(cls, arg, validation_metadata: ValidationMetadata): path_to_schemas = defaultdict(set) for allof_cls in cls.MetaOapg.all_of(): if validation_metadata.validation_ran_earlier(allof_cls): + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue other_path_to_schemas = allof_cls._validate_oapg(arg, validation_metadata=validation_metadata) update(path_to_schemas, other_path_to_schemas) @@ -1865,6 +1875,7 @@ def __get_oneof_class( continue if validation_metadata.validation_ran_earlier(oneof_cls): oneof_classes.append(oneof_cls) + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue try: path_to_schemas = oneof_cls._validate_oapg(arg, validation_metadata=validation_metadata) @@ -1898,6 +1909,7 @@ def __get_anyof_classes( for anyof_cls in cls.MetaOapg.any_of(): if validation_metadata.validation_ran_earlier(anyof_cls): anyof_classes.append(anyof_cls) + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue try: @@ -2011,6 +2023,7 @@ def _validate_oapg( if discriminated_cls is not None and not updated_vm.validation_ran_earlier(discriminated_cls): # TODO use an exception from this package here + add_deeper_validated_schemas(updated_vm, path_to_schemas) assert discriminated_cls in path_to_schemas[updated_vm.path_to_item] return path_to_schemas diff --git a/samples/openapi3/client/features/nonCompliantUseDiscriminatorIfCompositionFails/python/this_package/schemas.py b/samples/openapi3/client/features/nonCompliantUseDiscriminatorIfCompositionFails/python/this_package/schemas.py index a88751a643d..5e117f6df3a 100644 --- a/samples/openapi3/client/features/nonCompliantUseDiscriminatorIfCompositionFails/python/this_package/schemas.py +++ b/samples/openapi3/client/features/nonCompliantUseDiscriminatorIfCompositionFails/python/this_package/schemas.py @@ -148,6 +148,19 @@ def validated_path_to_schemas(self) -> typing.Dict[typing.Tuple[typing.Union[str return self.get('validated_path_to_schemas') +def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_to_schemas: dict): + # this is called if validation_ran_earlier and current and deeper locations need to be added + current_path_to_item = validation_metadata.path_to_item + other_path_to_schemas = {} + for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items(): + if len(path_to_item) < len(current_path_to_item): + continue + path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item + if path_begins_with_current_path: + other_path_to_schemas[path_to_item] = schemas + update(path_to_schemas, other_path_to_schemas) + + class Singleton: """ Enums and singletons are the same @@ -392,9 +405,9 @@ def __get_new_cls( because value is of the correct type, and validation was run earlier when the instance was created """ _path_to_schemas = {} - if validation_metadata.validated_path_to_schemas: - update(_path_to_schemas, validation_metadata.validated_path_to_schemas) - if not validation_metadata.validation_ran_earlier(cls): + if validation_metadata.validation_ran_earlier(cls): + add_deeper_validated_schemas(validation_metadata, _path_to_schemas) + else: other_path_to_schemas = cls._validate_oapg(arg, validation_metadata=validation_metadata) update(_path_to_schemas, other_path_to_schemas) # loop through it make a new class for each entry @@ -1332,6 +1345,7 @@ def __validate_items(cls, list_items, validation_metadata: ValidationMetadata): validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if item_validation_metadata.validation_ran_earlier(item_cls): + add_deeper_validated_schemas(item_validation_metadata, path_to_schemas) continue other_path_to_schemas = item_cls._validate_oapg( value, validation_metadata=item_validation_metadata) @@ -1595,6 +1609,7 @@ def __validate_args(cls, arg, validation_metadata: ValidationMetadata): validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if arg_validation_metadata.validation_ran_earlier(schema): + add_deeper_validated_schemas(arg_validation_metadata, path_to_schemas) continue other_path_to_schemas = schema._validate_oapg(value, validation_metadata=arg_validation_metadata) update(path_to_schemas, other_path_to_schemas) @@ -1683,6 +1698,7 @@ def _validate_oapg( validated_path_to_schemas=validation_metadata.validated_path_to_schemas ) if updated_vm.validation_ran_earlier(discriminated_cls): + add_deeper_validated_schemas(updated_vm, _path_to_schemas) return _path_to_schemas other_path_to_schemas = discriminated_cls._validate_oapg(arg, validation_metadata=updated_vm) update(_path_to_schemas, other_path_to_schemas) @@ -1781,18 +1797,11 @@ def cast_to_allowed_types( if isinstance(arg, Schema): # store the already run validations schema_classes = set() - source_schema_was_unset = len(arg.__class__.__bases__) == 2 and UnsetAnyTypeSchema in arg.__class__.__bases__ - if not source_schema_was_unset: - """ - Do not include UnsetAnyTypeSchema and its base class because - it did not exist in the original spec schema definition - It was added to ensure that all instances are of type Schema and the allowed base types - """ - for cls in arg.__class__.__bases__: - if cls is Singleton: - # Skip Singleton - continue - schema_classes.add(cls) + for cls in arg.__class__.__bases__: + if cls is Singleton: + # Skip Singleton + continue + schema_classes.add(cls) validated_path_to_schemas[path_to_item] = schema_classes type_error = ApiTypeError(f"Invalid type. Required value type is str and passed type was {type(arg)} at {path_to_item}") @@ -1845,6 +1854,7 @@ def __get_allof_classes(cls, arg, validation_metadata: ValidationMetadata): path_to_schemas = defaultdict(set) for allof_cls in cls.MetaOapg.all_of(): if validation_metadata.validation_ran_earlier(allof_cls): + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue other_path_to_schemas = allof_cls._validate_oapg(arg, validation_metadata=validation_metadata) update(path_to_schemas, other_path_to_schemas) @@ -1865,6 +1875,7 @@ def __get_oneof_class( continue if validation_metadata.validation_ran_earlier(oneof_cls): oneof_classes.append(oneof_cls) + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue try: path_to_schemas = oneof_cls._validate_oapg(arg, validation_metadata=validation_metadata) @@ -1914,6 +1925,7 @@ def __get_anyof_classes( for anyof_cls in cls.MetaOapg.any_of(): if validation_metadata.validation_ran_earlier(anyof_cls): anyof_classes.append(anyof_cls) + add_deeper_validated_schemas(validation_metadata, path_to_schemas) continue try: @@ -2037,6 +2049,7 @@ def _validate_oapg( if discriminated_cls is not None and not updated_vm.validation_ran_earlier(discriminated_cls): # TODO use an exception from this package here + add_deeper_validated_schemas(updated_vm, path_to_schemas) assert discriminated_cls in path_to_schemas[updated_vm.path_to_item] return path_to_schemas diff --git a/samples/openapi3/client/petstore/python/.openapi-generator/VERSION b/samples/openapi3/client/petstore/python/.openapi-generator/VERSION index 717311e32e3..e4c0d46e55f 100644 --- a/samples/openapi3/client/petstore/python/.openapi-generator/VERSION +++ b/samples/openapi3/client/petstore/python/.openapi-generator/VERSION @@ -1 +1 @@ -unset \ No newline at end of file +1.0.3 \ No newline at end of file