@@ -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