Skip to content

Commit b123f18

Browse files
committed
Pull out resolving JSON Pointers.
1 parent 6d2851b commit b123f18

File tree

1 file changed

+27
-22
lines changed

1 file changed

+27
-22
lines changed

referencing/_core.py

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,25 @@ def from_resource(
4343
raise UnidentifiedResource(resource)
4444
return cls(resource=resource, specification=specification)
4545

46+
def pointer(self, base_uri: str, pointer: str) -> tuple[str, Schema]:
47+
"""
48+
Resolve the given JSON pointer, returning a base URI and resource.
49+
"""
50+
resource = self.resource
51+
for segment in unquote(pointer[1:]).split("/"):
52+
if isinstance(resource, Sequence):
53+
segment = int(segment) # type: ignore
54+
else:
55+
segment = segment.replace("~1", "/").replace("~0", "~")
56+
resource = resource[segment] # type: ignore # this can't be a bool
57+
# FIXME: this is wrong, we need to know that we are crossing
58+
# the boundary of a *schema* specifically
59+
if not isinstance(resource, Sequence):
60+
id = self._specification.id_of(resource)
61+
if id is not None:
62+
base_uri = urljoin(base_uri, id)
63+
return base_uri, resource
64+
4665
def id(self):
4766
return self._specification.id_of(self.resource)
4867

@@ -226,31 +245,17 @@ def lookup(self, ref: str) -> tuple[Schema, Resolver]:
226245
uri, fragment = urldefrag(urljoin(self._base_uri, ref))
227246

228247
resource, anchors, registry = self._registry.resource_at(uri)
229-
base_uri = uri
230-
target = resource.resource
231248

232249
if fragment.startswith("/"):
233-
segments = unquote(fragment[1:]).split("/")
234-
for segment in segments:
235-
if isinstance(target, Sequence):
236-
segment = int(segment) # type: ignore
237-
else:
238-
segment = segment.replace("~1", "/").replace("~0", "~")
239-
target = target[segment] # type: ignore # this can't be a bool
240-
# FIXME: this is wrong, we need to know that we are crossing
241-
# the boundary of a *schema* specifically
242-
if not isinstance(target, Sequence):
243-
id = resource._specification.id_of(target)
244-
if id is not None:
245-
base_uri = urljoin(base_uri, id)
246-
elif fragment:
247-
resource, uri = anchors[fragment].resolve(resolver=self, uri=uri)
248-
target = resource.resource
249-
250-
id = resource.id()
251-
if id is not None:
252-
base_uri = urljoin(self._base_uri, id)
250+
base_uri, target = resource.pointer(base_uri=uri, pointer=fragment)
253251
else:
252+
if fragment:
253+
resource, uri = anchors[fragment].resolve(
254+
resolver=self,
255+
uri=uri,
256+
)
257+
258+
base_uri, target = uri, resource.resource
254259
id = resource.id()
255260
if id is not None:
256261
base_uri = urljoin(self._base_uri, id).rstrip("#")

0 commit comments

Comments
 (0)