Skip to content

Commit

Permalink
schema properties validation recursion fix
Browse files Browse the repository at this point in the history
  • Loading branch information
p1c2u committed Feb 2, 2023
1 parent ee153b2 commit 41ae7f1
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 8 deletions.
7 changes: 5 additions & 2 deletions openapi_spec_validator/schemas/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
from typing import Tuple

if sys.version_info >= (3, 9):
from importlib.resources import as_file, files
from importlib.resources import as_file
from importlib.resources import files
else:
from importlib_resources import as_file, files
from importlib_resources import as_file
from importlib_resources import files

from jsonschema_spec.readers import FilePathReader


Expand Down
11 changes: 9 additions & 2 deletions openapi_spec_validator/validation/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def __init__(
self.resolver_handlers = resolver_handlers

self.operation_ids_registry: Optional[List[str]] = None
self.schema_ids_registry: Optional[List[str]] = None
self.resolver = None

def validate(
Expand All @@ -82,6 +83,7 @@ def iter_errors(
self, instance: Mapping[Hashable, Any], spec_url: str = ""
) -> Iterator[ValidationError]:
self.operation_ids_registry = []
self.schema_ids_registry = []
self.resolver = self._get_resolver(spec_url, instance)

yield from self.schema_validator.iter_errors(instance)
Expand Down Expand Up @@ -248,7 +250,12 @@ def _iter_schema_errors(
if not hasattr(schema.content(), "__getitem__"):
return

schema_type = schema.getkey("type")
assert self.schema_ids_registry is not None
schema_id = id(schema.content())
if schema_id in self.schema_ids_registry:
return
self.schema_ids_registry.append(schema_id)

nested_properties = []
if "allOf" in schema:
all_of = schema / "allOf"
Expand Down Expand Up @@ -294,7 +301,7 @@ def _iter_schema_errors(
)

if "properties" in schema:
props = schema /"properties"
props = schema / "properties"
for _, prop_schema in props.items():
yield from self._iter_schema_errors(
prop_schema,
Expand Down
16 changes: 16 additions & 0 deletions tests/integration/data/v3.0/property-recursive.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
openapi: 3.0.0
info:
version: '1.0.0'
title: 'Some Schema'
paths: {}
components:
schemas:
SomeDataType:
type: object
properties:
id:
type: integer
prop1:
$ref: '#/components/schemas/SomeDataType'
prop2:
type: string
8 changes: 4 additions & 4 deletions tests/integration/validation/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,9 @@ def test_parameter_custom_format_checker_not_found(self, validator_v30):
errors_list = list(errors)
assert errors_list == []

def test_parameter_default_value_custom_format_invalid(self, validator_v30):
def test_parameter_default_value_custom_format_invalid(
self, validator_v30
):
from openapi_schema_validator import oas30_format_checker

@oas30_format_checker.checks("custom")
Expand Down Expand Up @@ -498,6 +500,4 @@ def validate(to_validate) -> bool:
errors_list = list(errors)
assert len(errors_list) == 1
assert errors_list[0].__class__ == OpenAPIValidationError
assert errors_list[0].message == (
"'invalid' is not a 'custom'"
)
assert errors_list[0].message == ("'invalid' is not a 'custom'")
1 change: 1 addition & 0 deletions tests/integration/validation/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def local_test_suite_file_path(self, test_file):
"petstore.yaml",
"petstore-separate/spec/openapi.yaml",
"parent-reference/openapi.yaml",
"property-recursive.yaml",
],
)
def test_valid(self, factory, validator_v30, spec_file):
Expand Down

0 comments on commit 41ae7f1

Please sign in to comment.