Skip to content
This repository was archived by the owner on Dec 25, 2024. It is now read-only.

Commit 8bf45d9

Browse files
authored
Fixes issue 81, model instance in new (#82)
* Adds and uses add_deeper_validated_schemas * Adds fix * Template updated with fix and pestore sample regenerated * Fixes length comparison * Further fix * Updates samples
1 parent 094a4f3 commit 8bf45d9

File tree

5 files changed

+151
-60
lines changed
  • modules/openapi-json-schema-generator/src/main/resources/python
  • samples/openapi3/client

5 files changed

+151
-60
lines changed

modules/openapi-json-schema-generator/src/main/resources/python/schemas.handlebars

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,19 @@ class ValidationMetadata(frozendict.frozendict):
141141
return self.get('validated_path_to_schemas')
142142

143143

144+
def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_to_schemas: dict):
145+
# this is called if validation_ran_earlier and current and deeper locations need to be added
146+
current_path_to_item = validation_metadata.path_to_item
147+
other_path_to_schemas = {}
148+
for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items():
149+
if len(path_to_item) < len(current_path_to_item):
150+
continue
151+
path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item
152+
if path_begins_with_current_path:
153+
other_path_to_schemas[path_to_item] = schemas
154+
update(path_to_schemas, other_path_to_schemas)
155+
156+
144157
class Singleton:
145158
"""
146159
Enums and singletons are the same
@@ -385,9 +398,9 @@ class Schema:
385398
because value is of the correct type, and validation was run earlier when the instance was created
386399
"""
387400
_path_to_schemas = {}
388-
if validation_metadata.validated_path_to_schemas:
389-
update(_path_to_schemas, validation_metadata.validated_path_to_schemas)
390-
if not validation_metadata.validation_ran_earlier(cls):
401+
if validation_metadata.validation_ran_earlier(cls):
402+
add_deeper_validated_schemas(validation_metadata, _path_to_schemas)
403+
else:
391404
other_path_to_schemas = cls._validate_oapg(arg, validation_metadata=validation_metadata)
392405
update(_path_to_schemas, other_path_to_schemas)
393406
# loop through it make a new class for each entry
@@ -1325,6 +1338,7 @@ class ListBase(ValidatorBase):
13251338
validated_path_to_schemas=validation_metadata.validated_path_to_schemas
13261339
)
13271340
if item_validation_metadata.validation_ran_earlier(item_cls):
1341+
add_deeper_validated_schemas(item_validation_metadata, path_to_schemas)
13281342
continue
13291343
other_path_to_schemas = item_cls._validate_oapg(
13301344
value, validation_metadata=item_validation_metadata)
@@ -1588,6 +1602,7 @@ class DictBase(Discriminable, ValidatorBase):
15881602
validated_path_to_schemas=validation_metadata.validated_path_to_schemas
15891603
)
15901604
if arg_validation_metadata.validation_ran_earlier(schema):
1605+
add_deeper_validated_schemas(arg_validation_metadata, path_to_schemas)
15911606
continue
15921607
other_path_to_schemas = schema._validate_oapg(value, validation_metadata=arg_validation_metadata)
15931608
update(path_to_schemas, other_path_to_schemas)
@@ -1676,6 +1691,7 @@ class DictBase(Discriminable, ValidatorBase):
16761691
validated_path_to_schemas=validation_metadata.validated_path_to_schemas
16771692
)
16781693
if updated_vm.validation_ran_earlier(discriminated_cls):
1694+
add_deeper_validated_schemas(updated_vm, _path_to_schemas)
16791695
return _path_to_schemas
16801696
other_path_to_schemas = discriminated_cls._validate_oapg(arg, validation_metadata=updated_vm)
16811697
update(_path_to_schemas, other_path_to_schemas)
@@ -1774,18 +1790,11 @@ def cast_to_allowed_types(
17741790
if isinstance(arg, Schema):
17751791
# store the already run validations
17761792
schema_classes = set()
1777-
source_schema_was_unset = len(arg.__class__.__bases__) == 2 and UnsetAnyTypeSchema in arg.__class__.__bases__
1778-
if not source_schema_was_unset:
1779-
"""
1780-
Do not include UnsetAnyTypeSchema and its base class because
1781-
it did not exist in the original spec schema definition
1782-
It was added to ensure that all instances are of type Schema and the allowed base types
1783-
"""
1784-
for cls in arg.__class__.__bases__:
1785-
if cls is Singleton:
1786-
# Skip Singleton
1787-
continue
1788-
schema_classes.add(cls)
1793+
for cls in arg.__class__.__bases__:
1794+
if cls is Singleton:
1795+
# Skip Singleton
1796+
continue
1797+
schema_classes.add(cls)
17891798
validated_path_to_schemas[path_to_item] = schema_classes
17901799

17911800
type_error = ApiTypeError(f"Invalid type. Required value type is str and passed type was {type(arg)} at {path_to_item}")
@@ -1838,6 +1847,7 @@ class ComposedBase(Discriminable):
18381847
path_to_schemas = defaultdict(set)
18391848
for allof_cls in cls.MetaOapg.all_of():
18401849
if validation_metadata.validation_ran_earlier(allof_cls):
1850+
add_deeper_validated_schemas(validation_metadata, path_to_schemas)
18411851
continue
18421852
other_path_to_schemas = allof_cls._validate_oapg(arg, validation_metadata=validation_metadata)
18431853
update(path_to_schemas, other_path_to_schemas)
@@ -1858,6 +1868,7 @@ class ComposedBase(Discriminable):
18581868
continue
18591869
if validation_metadata.validation_ran_earlier(oneof_cls):
18601870
oneof_classes.append(oneof_cls)
1871+
add_deeper_validated_schemas(validation_metadata, path_to_schemas)
18611872
continue
18621873
try:
18631874
path_to_schemas = oneof_cls._validate_oapg(arg, validation_metadata=validation_metadata)
@@ -1915,6 +1926,7 @@ class ComposedBase(Discriminable):
19151926
for anyof_cls in cls.MetaOapg.any_of():
19161927
if validation_metadata.validation_ran_earlier(anyof_cls):
19171928
anyof_classes.append(anyof_cls)
1929+
add_deeper_validated_schemas(validation_metadata, path_to_schemas)
19181930
continue
19191931

19201932
try:
@@ -2044,6 +2056,7 @@ class ComposedBase(Discriminable):
20442056

20452057
if discriminated_cls is not None and not updated_vm.validation_ran_earlier(discriminated_cls):
20462058
# TODO use an exception from this package here
2059+
add_deeper_validated_schemas(updated_vm, path_to_schemas)
20472060
assert discriminated_cls in path_to_schemas[updated_vm.path_to_item]
20482061
return path_to_schemas
20492062

samples/openapi3/client/3_0_3_unit_test/python/unit_test_api/schemas.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,19 @@ def validated_path_to_schemas(self) -> typing.Dict[typing.Tuple[typing.Union[str
148148
return self.get('validated_path_to_schemas')
149149

150150

151+
def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_to_schemas: dict):
152+
# this is called if validation_ran_earlier and current and deeper locations need to be added
153+
current_path_to_item = validation_metadata.path_to_item
154+
other_path_to_schemas = {}
155+
for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items():
156+
if len(path_to_item) < len(current_path_to_item):
157+
continue
158+
path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item
159+
if path_begins_with_current_path:
160+
other_path_to_schemas[path_to_item] = schemas
161+
update(path_to_schemas, other_path_to_schemas)
162+
163+
151164
class Singleton:
152165
"""
153166
Enums and singletons are the same
@@ -392,9 +405,9 @@ def __get_new_cls(
392405
because value is of the correct type, and validation was run earlier when the instance was created
393406
"""
394407
_path_to_schemas = {}
395-
if validation_metadata.validated_path_to_schemas:
396-
update(_path_to_schemas, validation_metadata.validated_path_to_schemas)
397-
if not validation_metadata.validation_ran_earlier(cls):
408+
if validation_metadata.validation_ran_earlier(cls):
409+
add_deeper_validated_schemas(validation_metadata, _path_to_schemas)
410+
else:
398411
other_path_to_schemas = cls._validate_oapg(arg, validation_metadata=validation_metadata)
399412
update(_path_to_schemas, other_path_to_schemas)
400413
# loop through it make a new class for each entry
@@ -1332,6 +1345,7 @@ def __validate_items(cls, list_items, validation_metadata: ValidationMetadata):
13321345
validated_path_to_schemas=validation_metadata.validated_path_to_schemas
13331346
)
13341347
if item_validation_metadata.validation_ran_earlier(item_cls):
1348+
add_deeper_validated_schemas(item_validation_metadata, path_to_schemas)
13351349
continue
13361350
other_path_to_schemas = item_cls._validate_oapg(
13371351
value, validation_metadata=item_validation_metadata)
@@ -1595,6 +1609,7 @@ def __validate_args(cls, arg, validation_metadata: ValidationMetadata):
15951609
validated_path_to_schemas=validation_metadata.validated_path_to_schemas
15961610
)
15971611
if arg_validation_metadata.validation_ran_earlier(schema):
1612+
add_deeper_validated_schemas(arg_validation_metadata, path_to_schemas)
15981613
continue
15991614
other_path_to_schemas = schema._validate_oapg(value, validation_metadata=arg_validation_metadata)
16001615
update(path_to_schemas, other_path_to_schemas)
@@ -1683,6 +1698,7 @@ def _validate_oapg(
16831698
validated_path_to_schemas=validation_metadata.validated_path_to_schemas
16841699
)
16851700
if updated_vm.validation_ran_earlier(discriminated_cls):
1701+
add_deeper_validated_schemas(updated_vm, _path_to_schemas)
16861702
return _path_to_schemas
16871703
other_path_to_schemas = discriminated_cls._validate_oapg(arg, validation_metadata=updated_vm)
16881704
update(_path_to_schemas, other_path_to_schemas)
@@ -1781,18 +1797,11 @@ def cast_to_allowed_types(
17811797
if isinstance(arg, Schema):
17821798
# store the already run validations
17831799
schema_classes = set()
1784-
source_schema_was_unset = len(arg.__class__.__bases__) == 2 and UnsetAnyTypeSchema in arg.__class__.__bases__
1785-
if not source_schema_was_unset:
1786-
"""
1787-
Do not include UnsetAnyTypeSchema and its base class because
1788-
it did not exist in the original spec schema definition
1789-
It was added to ensure that all instances are of type Schema and the allowed base types
1790-
"""
1791-
for cls in arg.__class__.__bases__:
1792-
if cls is Singleton:
1793-
# Skip Singleton
1794-
continue
1795-
schema_classes.add(cls)
1800+
for cls in arg.__class__.__bases__:
1801+
if cls is Singleton:
1802+
# Skip Singleton
1803+
continue
1804+
schema_classes.add(cls)
17961805
validated_path_to_schemas[path_to_item] = schema_classes
17971806

17981807
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):
18451854
path_to_schemas = defaultdict(set)
18461855
for allof_cls in cls.MetaOapg.all_of():
18471856
if validation_metadata.validation_ran_earlier(allof_cls):
1857+
add_deeper_validated_schemas(validation_metadata, path_to_schemas)
18481858
continue
18491859
other_path_to_schemas = allof_cls._validate_oapg(arg, validation_metadata=validation_metadata)
18501860
update(path_to_schemas, other_path_to_schemas)
@@ -1865,6 +1875,7 @@ def __get_oneof_class(
18651875
continue
18661876
if validation_metadata.validation_ran_earlier(oneof_cls):
18671877
oneof_classes.append(oneof_cls)
1878+
add_deeper_validated_schemas(validation_metadata, path_to_schemas)
18681879
continue
18691880
try:
18701881
path_to_schemas = oneof_cls._validate_oapg(arg, validation_metadata=validation_metadata)
@@ -1898,6 +1909,7 @@ def __get_anyof_classes(
18981909
for anyof_cls in cls.MetaOapg.any_of():
18991910
if validation_metadata.validation_ran_earlier(anyof_cls):
19001911
anyof_classes.append(anyof_cls)
1912+
add_deeper_validated_schemas(validation_metadata, path_to_schemas)
19011913
continue
19021914

19031915
try:
@@ -2011,6 +2023,7 @@ def _validate_oapg(
20112023

20122024
if discriminated_cls is not None and not updated_vm.validation_ran_earlier(discriminated_cls):
20132025
# TODO use an exception from this package here
2026+
add_deeper_validated_schemas(updated_vm, path_to_schemas)
20142027
assert discriminated_cls in path_to_schemas[updated_vm.path_to_item]
20152028
return path_to_schemas
20162029

samples/openapi3/client/features/nonCompliantUseDiscriminatorIfCompositionFails/python/this_package/schemas.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,19 @@ def validated_path_to_schemas(self) -> typing.Dict[typing.Tuple[typing.Union[str
148148
return self.get('validated_path_to_schemas')
149149

150150

151+
def add_deeper_validated_schemas(validation_metadata: ValidationMetadata, path_to_schemas: dict):
152+
# this is called if validation_ran_earlier and current and deeper locations need to be added
153+
current_path_to_item = validation_metadata.path_to_item
154+
other_path_to_schemas = {}
155+
for path_to_item, schemas in validation_metadata.validated_path_to_schemas.items():
156+
if len(path_to_item) < len(current_path_to_item):
157+
continue
158+
path_begins_with_current_path = path_to_item[:len(current_path_to_item)] == current_path_to_item
159+
if path_begins_with_current_path:
160+
other_path_to_schemas[path_to_item] = schemas
161+
update(path_to_schemas, other_path_to_schemas)
162+
163+
151164
class Singleton:
152165
"""
153166
Enums and singletons are the same
@@ -392,9 +405,9 @@ def __get_new_cls(
392405
because value is of the correct type, and validation was run earlier when the instance was created
393406
"""
394407
_path_to_schemas = {}
395-
if validation_metadata.validated_path_to_schemas:
396-
update(_path_to_schemas, validation_metadata.validated_path_to_schemas)
397-
if not validation_metadata.validation_ran_earlier(cls):
408+
if validation_metadata.validation_ran_earlier(cls):
409+
add_deeper_validated_schemas(validation_metadata, _path_to_schemas)
410+
else:
398411
other_path_to_schemas = cls._validate_oapg(arg, validation_metadata=validation_metadata)
399412
update(_path_to_schemas, other_path_to_schemas)
400413
# loop through it make a new class for each entry
@@ -1332,6 +1345,7 @@ def __validate_items(cls, list_items, validation_metadata: ValidationMetadata):
13321345
validated_path_to_schemas=validation_metadata.validated_path_to_schemas
13331346
)
13341347
if item_validation_metadata.validation_ran_earlier(item_cls):
1348+
add_deeper_validated_schemas(item_validation_metadata, path_to_schemas)
13351349
continue
13361350
other_path_to_schemas = item_cls._validate_oapg(
13371351
value, validation_metadata=item_validation_metadata)
@@ -1595,6 +1609,7 @@ def __validate_args(cls, arg, validation_metadata: ValidationMetadata):
15951609
validated_path_to_schemas=validation_metadata.validated_path_to_schemas
15961610
)
15971611
if arg_validation_metadata.validation_ran_earlier(schema):
1612+
add_deeper_validated_schemas(arg_validation_metadata, path_to_schemas)
15981613
continue
15991614
other_path_to_schemas = schema._validate_oapg(value, validation_metadata=arg_validation_metadata)
16001615
update(path_to_schemas, other_path_to_schemas)
@@ -1683,6 +1698,7 @@ def _validate_oapg(
16831698
validated_path_to_schemas=validation_metadata.validated_path_to_schemas
16841699
)
16851700
if updated_vm.validation_ran_earlier(discriminated_cls):
1701+
add_deeper_validated_schemas(updated_vm, _path_to_schemas)
16861702
return _path_to_schemas
16871703
other_path_to_schemas = discriminated_cls._validate_oapg(arg, validation_metadata=updated_vm)
16881704
update(_path_to_schemas, other_path_to_schemas)
@@ -1781,18 +1797,11 @@ def cast_to_allowed_types(
17811797
if isinstance(arg, Schema):
17821798
# store the already run validations
17831799
schema_classes = set()
1784-
source_schema_was_unset = len(arg.__class__.__bases__) == 2 and UnsetAnyTypeSchema in arg.__class__.__bases__
1785-
if not source_schema_was_unset:
1786-
"""
1787-
Do not include UnsetAnyTypeSchema and its base class because
1788-
it did not exist in the original spec schema definition
1789-
It was added to ensure that all instances are of type Schema and the allowed base types
1790-
"""
1791-
for cls in arg.__class__.__bases__:
1792-
if cls is Singleton:
1793-
# Skip Singleton
1794-
continue
1795-
schema_classes.add(cls)
1800+
for cls in arg.__class__.__bases__:
1801+
if cls is Singleton:
1802+
# Skip Singleton
1803+
continue
1804+
schema_classes.add(cls)
17961805
validated_path_to_schemas[path_to_item] = schema_classes
17971806

17981807
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):
18451854
path_to_schemas = defaultdict(set)
18461855
for allof_cls in cls.MetaOapg.all_of():
18471856
if validation_metadata.validation_ran_earlier(allof_cls):
1857+
add_deeper_validated_schemas(validation_metadata, path_to_schemas)
18481858
continue
18491859
other_path_to_schemas = allof_cls._validate_oapg(arg, validation_metadata=validation_metadata)
18501860
update(path_to_schemas, other_path_to_schemas)
@@ -1865,6 +1875,7 @@ def __get_oneof_class(
18651875
continue
18661876
if validation_metadata.validation_ran_earlier(oneof_cls):
18671877
oneof_classes.append(oneof_cls)
1878+
add_deeper_validated_schemas(validation_metadata, path_to_schemas)
18681879
continue
18691880
try:
18701881
path_to_schemas = oneof_cls._validate_oapg(arg, validation_metadata=validation_metadata)
@@ -1914,6 +1925,7 @@ def __get_anyof_classes(
19141925
for anyof_cls in cls.MetaOapg.any_of():
19151926
if validation_metadata.validation_ran_earlier(anyof_cls):
19161927
anyof_classes.append(anyof_cls)
1928+
add_deeper_validated_schemas(validation_metadata, path_to_schemas)
19171929
continue
19181930

19191931
try:
@@ -2037,6 +2049,7 @@ def _validate_oapg(
20372049

20382050
if discriminated_cls is not None and not updated_vm.validation_ran_earlier(discriminated_cls):
20392051
# TODO use an exception from this package here
2052+
add_deeper_validated_schemas(updated_vm, path_to_schemas)
20402053
assert discriminated_cls in path_to_schemas[updated_vm.path_to_item]
20412054
return path_to_schemas
20422055

0 commit comments

Comments
 (0)