@@ -43,6 +43,25 @@ def from_resource(
43
43
raise UnidentifiedResource (resource )
44
44
return cls (resource = resource , specification = specification )
45
45
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
+
46
65
def id (self ):
47
66
return self ._specification .id_of (self .resource )
48
67
@@ -226,31 +245,17 @@ def lookup(self, ref: str) -> tuple[Schema, Resolver]:
226
245
uri , fragment = urldefrag (urljoin (self ._base_uri , ref ))
227
246
228
247
resource , anchors , registry = self ._registry .resource_at (uri )
229
- base_uri = uri
230
- target = resource .resource
231
248
232
249
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 )
253
251
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
254
259
id = resource .id ()
255
260
if id is not None :
256
261
base_uri = urljoin (self ._base_uri , id ).rstrip ("#" )
0 commit comments