Skip to content

Commit fb85c66

Browse files
committed
Revert "Extend dynamicRef keyword"
It needs performance optimization. See #941. This reverts commit 12c791e.
1 parent 3b2f0f3 commit fb85c66

File tree

5 files changed

+34
-100
lines changed

5 files changed

+34
-100
lines changed

Diff for: CHANGELOG.rst

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ v4.5.0
33

44
* Validator classes for each version now maintain references to the correct
55
corresponding format checker (#905)
6-
* Support for ``$dynamicRef`` has been improved (#886)
76
* Development has moved to a `GitHub organization
87
<https://github.com/python-jsonschema/>`_.
98
No functional behavior changes are expected from the change.

Diff for: jsonschema/_utils.py

-83
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from collections import deque
21
from collections.abc import Mapping, MutableMapping, Sequence
32
from urllib.parse import urlsplit
43
import itertools
@@ -347,85 +346,3 @@ def find_evaluated_property_keys_by_schema(validator, instance, schema):
347346
)
348347

349348
return evaluated_keys
350-
351-
352-
def _schema_is_referenced(schema, parent_schema):
353-
"""
354-
Checks if a schema is referenced by another schema
355-
"""
356-
return (
357-
"$id" in schema
358-
and "$ref" in parent_schema
359-
and parent_schema["$ref"] == schema["$id"]
360-
)
361-
362-
363-
def _find_dynamic_anchor_extender(validator, scopes, fragment, schema):
364-
"""
365-
Find a schema that extends the dynamic anchor
366-
"""
367-
for url in scopes:
368-
with validator.resolver.resolving(url) as parent_schema:
369-
if _schema_is_referenced(schema, parent_schema):
370-
return validator.resolver.resolve_fragment(
371-
parent_schema,
372-
fragment,
373-
)
374-
375-
376-
def _find_dynamic_anchor_intermediate(validator, scopes, fragment):
377-
"""
378-
Find a schema that extends the dynamic anchor by an intermediate schema
379-
"""
380-
for url in scopes:
381-
with validator.resolver.resolving(url) as schema:
382-
if "$id" in schema:
383-
for intermediate_url in scopes:
384-
with validator.resolver.resolving(
385-
intermediate_url) as intermediate_schema:
386-
for subschema in search_schema(
387-
intermediate_schema, match_keyword("$ref")):
388-
if _schema_is_referenced(subschema, schema):
389-
return _find_dynamic_anchor_extender(
390-
validator,
391-
scopes,
392-
fragment,
393-
subschema,
394-
)
395-
396-
397-
def dynamic_anchor_extender(validator, scopes, fragment, schema, subschema):
398-
extender_schema = _find_dynamic_anchor_extender(
399-
validator, scopes, fragment, schema,
400-
)
401-
if not extender_schema:
402-
extender_schema = _find_dynamic_anchor_extender(
403-
validator, scopes, fragment, subschema,
404-
)
405-
if not extender_schema:
406-
extender_schema = _find_dynamic_anchor_intermediate(
407-
validator, scopes, fragment,
408-
)
409-
410-
return extender_schema
411-
412-
413-
def match_keyword(keyword):
414-
def matcher(value):
415-
if keyword in value:
416-
yield value
417-
return matcher
418-
419-
420-
def search_schema(schema, matcher):
421-
"""Breadth-first search routine."""
422-
values = deque([schema])
423-
while values:
424-
value = values.pop()
425-
if isinstance(value, list):
426-
values.extendleft(value)
427-
continue
428-
if not isinstance(value, dict):
429-
continue
430-
yield from matcher(value)
431-
values.extendleft(value.values())

Diff for: jsonschema/_validators.py

+2-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import re
44

55
from jsonschema._utils import (
6-
dynamic_anchor_extender,
76
ensure_list,
87
equal,
98
extras_msg,
@@ -303,21 +302,14 @@ def ref(validator, ref, instance, schema):
303302

304303
def dynamicRef(validator, dynamicRef, instance, schema):
305304
_, fragment = urldefrag(dynamicRef)
305+
306306
for url in validator.resolver._scopes_stack:
307307
lookup_url = urljoin(url, dynamicRef)
308308
with validator.resolver.resolving(lookup_url) as subschema:
309309
if ("$dynamicAnchor" in subschema
310310
and fragment == subschema["$dynamicAnchor"]):
311-
scope_stack = list(validator.resolver._scopes_stack)
312-
scope_stack.reverse()
313-
extended_schema = dynamic_anchor_extender(
314-
validator, scope_stack, fragment, schema, subschema,
315-
)
316-
if extended_schema:
317-
yield from validator.descend(instance, extended_schema)
318-
break
319-
320311
yield from validator.descend(instance, subschema)
312+
break
321313
else:
322314
with validator.resolver.resolving(dynamicRef) as subschema:
323315
yield from validator.descend(instance, subschema)

Diff for: jsonschema/tests/test_jsonschema_test_suite.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,15 @@ def leap_second(test):
395395
skip=lambda test: (
396396
narrow_unicode_build(test)
397397
or skip(
398-
message="These tests require an extension or the url resolver.",
398+
message="dynamicRef support isn't working yet.",
399+
subject="dynamicRef",
400+
)(test)
401+
or skip(
402+
message="These tests depends on dynamicRef working.",
403+
subject="defs",
404+
)(test)
405+
or skip(
406+
message="These tests depends on dynamicRef working.",
399407
subject="anchor",
400408
case_description="same $anchor with different base uri",
401409
)(test)

Diff for: jsonschema/validators.py

+23-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
from __future__ import annotations
55

6+
from collections import deque
67
from collections.abc import Sequence
78
from functools import lru_cache
89
from urllib.parse import unquote, urldefrag, urljoin, urlsplit
@@ -805,7 +806,7 @@ def _find_in_referrer(self, key):
805806
@lru_cache() # noqa: B019
806807
def _get_subschemas_cache(self):
807808
cache = {key: [] for key in _SUBSCHEMAS_KEYWORDS}
808-
for keyword, subschema in _utils.search_schema(
809+
for keyword, subschema in _search_schema(
809810
self.referrer, _match_subschema_keywords,
810811
):
811812
cache[keyword].append(subschema)
@@ -879,10 +880,7 @@ def resolve_fragment(self, document, fragment):
879880
else:
880881

881882
def find(key):
882-
yield from _utils.search_schema(
883-
document,
884-
_utils.match_keyword(key),
885-
)
883+
yield from _search_schema(document, _match_keyword(key))
886884

887885
for keyword in ["$anchor", "$dynamicAnchor"]:
888886
for subschema in find(keyword):
@@ -968,12 +966,32 @@ def resolve_remote(self, uri):
968966
_SUBSCHEMAS_KEYWORDS = ("$id", "id", "$anchor", "$dynamicAnchor")
969967

970968

969+
def _match_keyword(keyword):
970+
971+
def matcher(value):
972+
if keyword in value:
973+
yield value
974+
975+
return matcher
976+
977+
971978
def _match_subschema_keywords(value):
972979
for keyword in _SUBSCHEMAS_KEYWORDS:
973980
if keyword in value:
974981
yield keyword, value
975982

976983

984+
def _search_schema(schema, matcher):
985+
"""Breadth-first search routine."""
986+
values = deque([schema])
987+
while values:
988+
value = values.pop()
989+
if not isinstance(value, dict):
990+
continue
991+
yield from matcher(value)
992+
values.extendleft(value.values())
993+
994+
977995
def validate(instance, schema, cls=None, *args, **kwargs):
978996
"""
979997
Validate an instance under the given schema.

0 commit comments

Comments
 (0)