Skip to content

Commit 2d3450d

Browse files
committed
Properly discover subresources while following pointers into items and dependencies.
1 parent f840c52 commit 2d3450d

File tree

3 files changed

+63
-9
lines changed

3 files changed

+63
-9
lines changed

referencing/_core.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,14 @@ def pointer(self, pointer: str, resolver: Resolver[D]) -> Resolved[D]:
183183
raise exceptions.PointerToNowhere(ref=pointer, resource=self)
184184

185185
segments.append(segment)
186+
last = resolver
186187
resolver = self._specification.maybe_in_subresource(
187188
segments=segments,
188189
resolver=resolver,
189190
subresource=self._specification.create_resource(contents), # type: ignore[reportUnknownArgumentType] # noqa: E501
190191
)
192+
if resolver is not last:
193+
segments = []
191194
return Resolved(contents=contents, resolver=resolver) # type: ignore[reportUnknownArgumentType] # noqa: E501
192195

193196

referencing/jsonschema.py

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,6 @@ def maybe_in_subresource(
237237
subresource: Resource[Any],
238238
) -> _Resolver[Any]:
239239
_segments = iter(segments)
240-
# FIXME: This is a ton of redone work, each time we recheck from the
241-
# beginning of the pointer, so long ones will just keep doing
242-
# that over and over again...
243240
for segment in _segments:
244241
if segment not in in_value and (
245242
segment not in in_child or next(_segments, None) is None
@@ -250,6 +247,60 @@ def maybe_in_subresource(
250247
return maybe_in_subresource
251248

252249

250+
def _maybe_in_subresource_crazy_items(
251+
in_value: Set[str] = frozenset(),
252+
in_subvalues: Set[str] = frozenset(),
253+
in_subarray: Set[str] = frozenset(),
254+
):
255+
in_child = in_subvalues | in_subarray
256+
257+
def maybe_in_subresource(
258+
segments: Sequence[int | str],
259+
resolver: _Resolver[Any],
260+
subresource: Resource[Any],
261+
) -> _Resolver[Any]:
262+
_segments = iter(segments)
263+
for segment in _segments:
264+
if segment == "items" and isinstance(
265+
subresource.contents, Mapping
266+
):
267+
return resolver.in_subresource(subresource)
268+
if segment not in in_value and (
269+
segment not in in_child or next(_segments, None) is None
270+
):
271+
return resolver
272+
return resolver.in_subresource(subresource)
273+
274+
return maybe_in_subresource
275+
276+
277+
def _maybe_in_subresource_crazy_items_dependencies(
278+
in_value: Set[str] = frozenset(),
279+
in_subvalues: Set[str] = frozenset(),
280+
in_subarray: Set[str] = frozenset(),
281+
):
282+
in_child = in_subvalues | in_subarray
283+
284+
def maybe_in_subresource(
285+
segments: Sequence[int | str],
286+
resolver: _Resolver[Any],
287+
subresource: Resource[Any],
288+
) -> _Resolver[Any]:
289+
_segments = iter(segments)
290+
for segment in _segments:
291+
if (
292+
segment == "items" or segment == "dependencies"
293+
) and isinstance(subresource.contents, Mapping):
294+
return resolver.in_subresource(subresource)
295+
if segment not in in_value and (
296+
segment not in in_child or next(_segments, None) is None
297+
):
298+
return resolver
299+
return resolver.in_subresource(subresource)
300+
301+
return maybe_in_subresource
302+
303+
253304
DRAFT202012 = Specification(
254305
name="draft2020-12",
255306
id_of=_dollar_id,
@@ -325,7 +376,7 @@ def maybe_in_subresource(
325376
},
326377
),
327378
anchors_in=_anchor_2019,
328-
maybe_in_subresource=_maybe_in_subresource(
379+
maybe_in_subresource=_maybe_in_subresource_crazy_items(
329380
in_value={
330381
"additionalItems",
331382
"additionalProperties",
@@ -366,7 +417,7 @@ def maybe_in_subresource(
366417
in_subvalues={"definitions", "patternProperties", "properties"},
367418
),
368419
anchors_in=_legacy_anchor_in_dollar_id,
369-
maybe_in_subresource=_maybe_in_subresource(
420+
maybe_in_subresource=_maybe_in_subresource_crazy_items_dependencies(
370421
in_value={
371422
"additionalItems",
372423
"additionalProperties",
@@ -396,7 +447,7 @@ def maybe_in_subresource(
396447
in_subvalues={"definitions", "patternProperties", "properties"},
397448
),
398449
anchors_in=_legacy_anchor_in_dollar_id,
399-
maybe_in_subresource=_maybe_in_subresource(
450+
maybe_in_subresource=_maybe_in_subresource_crazy_items_dependencies(
400451
in_value={
401452
"additionalItems",
402453
"additionalProperties",
@@ -417,7 +468,7 @@ def maybe_in_subresource(
417468
in_subvalues={"definitions", "patternProperties", "properties"},
418469
),
419470
anchors_in=_legacy_anchor_in_id,
420-
maybe_in_subresource=_maybe_in_subresource(
471+
maybe_in_subresource=_maybe_in_subresource_crazy_items_dependencies(
421472
in_value={"additionalItems", "additionalProperties", "not"},
422473
in_subarray={"allOf", "anyOf", "oneOf"},
423474
in_subvalues={"definitions", "patternProperties", "properties"},
@@ -432,7 +483,7 @@ def maybe_in_subresource(
432483
in_subvalues={"definitions", "patternProperties", "properties"},
433484
),
434485
anchors_in=_legacy_anchor_in_id,
435-
maybe_in_subresource=_maybe_in_subresource(
486+
maybe_in_subresource=_maybe_in_subresource_crazy_items_dependencies(
436487
in_value={"additionalItems", "additionalProperties"},
437488
in_subarray={"extends"},
438489
in_subvalues={"definitions", "patternProperties", "properties"},

0 commit comments

Comments
 (0)