Skip to content

Commit 0b4a1f2

Browse files
authored
Merge pull request #250 from python-openapi/fix/narrower-handling-around-unresolved-refs
Narrower handling around unresolved refs
2 parents f203cde + e8e1c16 commit 0b4a1f2

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

openapi_schema_validator/_keywords.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from jsonschema._utils import find_additional_properties
1111
from jsonschema.exceptions import FormatError
1212
from jsonschema.exceptions import ValidationError
13+
from jsonschema.exceptions import _WrappedReferencingError
1314

1415

1516
def handle_discriminator(
@@ -53,7 +54,7 @@ def handle_discriminator(
5354

5455
try:
5556
validator._validate_reference(ref=ref, instance=instance)
56-
except Exception:
57+
except _WrappedReferencingError:
5758
yield ValidationError(
5859
f"{instance!r} reference {ref!r} could not be resolved",
5960
context=[],

tests/integration/test_validators.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
from base64 import b64encode
2+
from typing import Any
3+
from typing import cast
24

35
import pytest
46
from jsonschema import ValidationError
7+
from jsonschema.exceptions import (
8+
_WrappedReferencingError as WrappedReferencingError,
9+
)
510
from referencing import Registry
611
from referencing import Resource
12+
from referencing.exceptions import InvalidAnchor
13+
from referencing.exceptions import NoSuchAnchor
14+
from referencing.exceptions import PointerToNowhere
715
from referencing.jsonschema import DRAFT202012
816

917
from openapi_schema_validator import OAS30ReadValidator
@@ -353,6 +361,96 @@ def test_oneof_required(self, validator_class):
353361
result = validator.validate(instance)
354362
assert result is None
355363

364+
@pytest.mark.parametrize(
365+
"mapping_ref",
366+
[
367+
"#/components/schemas/Missing",
368+
"#missing-anchor",
369+
"#bad/frag",
370+
],
371+
)
372+
def test_discriminator_handles_unresolvable_reference_kinds(
373+
self, mapping_ref
374+
):
375+
schema = {
376+
"oneOf": [{"$ref": "#/components/schemas/MountainHiking"}],
377+
"discriminator": {
378+
"propertyName": "discipline",
379+
"mapping": {"mountain_hiking": mapping_ref},
380+
},
381+
"components": {
382+
"schemas": {
383+
"MountainHiking": {
384+
"type": "object",
385+
"properties": {
386+
"discipline": {"type": "string"},
387+
"length": {"type": "integer"},
388+
},
389+
"required": ["discipline", "length"],
390+
},
391+
},
392+
},
393+
}
394+
395+
validator = OAS30Validator(
396+
schema,
397+
format_checker=oas30_format_checker,
398+
)
399+
with pytest.raises(
400+
ValidationError,
401+
match=f"reference '{mapping_ref}' could not be resolved",
402+
):
403+
validator.validate(
404+
{
405+
"discipline": "mountain_hiking",
406+
"length": 10,
407+
}
408+
)
409+
410+
@pytest.mark.parametrize(
411+
"mapping_ref, expected_cause",
412+
[
413+
("#/components/schemas/Missing", PointerToNowhere),
414+
("#missing-anchor", NoSuchAnchor),
415+
("#bad/frag", InvalidAnchor),
416+
],
417+
)
418+
def test_discriminator_unresolvable_reference_causes(
419+
self, mapping_ref, expected_cause
420+
):
421+
schema = {
422+
"oneOf": [{"$ref": "#/components/schemas/MountainHiking"}],
423+
"discriminator": {
424+
"propertyName": "discipline",
425+
"mapping": {"mountain_hiking": mapping_ref},
426+
},
427+
"components": {
428+
"schemas": {
429+
"MountainHiking": {
430+
"type": "object",
431+
"properties": {
432+
"discipline": {"type": "string"},
433+
"length": {"type": "integer"},
434+
},
435+
"required": ["discipline", "length"],
436+
},
437+
},
438+
},
439+
}
440+
441+
validator = OAS30Validator(
442+
schema,
443+
format_checker=oas30_format_checker,
444+
)
445+
446+
with pytest.raises(WrappedReferencingError) as exc_info:
447+
cast(Any, validator)._validate_reference(
448+
ref=mapping_ref,
449+
instance={"discipline": "mountain_hiking", "length": 10},
450+
)
451+
452+
assert isinstance(exc_info.value.__cause__, expected_cause)
453+
356454
@pytest.mark.parametrize(
357455
"schema_type",
358456
[

0 commit comments

Comments
 (0)