@@ -66,6 +66,9 @@ def added_to(self, registry: Registry):
6666 return registry .with_anchor (anchor = self )
6767
6868
69+ AnchorType = Union [Anchor , DynamicAnchor ]
70+
71+
6972@frozen
7073class IdentifiedResource :
7174
@@ -82,28 +85,31 @@ def added_to(self, registry: Registry):
8285@frozen
8386class Registry :
8487
85- _contents : PMap [str , tuple [Schema , PMap [str , Schema ]]] = attrs .field (
88+ _contents : PMap [str , tuple [Schema , PMap [str , AnchorType ]]] = attrs .field (
8689 default = m (),
8790 repr = lambda value : f"({ len (value )} entries)" ,
8891 )
8992
90- def resource_at (self , uri ):
91- return self ._contents [uri ]
93+ def resource_at (self , uri ) -> Schema :
94+ return self ._contents [uri ][0 ]
95+
96+ def anchor_at (self , uri , name ) -> AnchorType :
97+ return self ._contents [uri ][1 ][name ]
9298
93- def with_resource (self , resource ):
99+ def with_resource (self , resource ) -> Registry :
94100 uri = id_of (resource )
95101 if uri is None :
96102 raise UnidentifiedResource (resource )
97103 return self .with_identified_resource (uri = uri , resource = resource )
98104
99- def with_identified_resource (self , uri , resource ):
105+ def with_identified_resource (self , uri , resource ) -> Registry :
100106 return self .with_resources ([(uri , resource )])
101107
102- def update (self , * registries : Registry ):
108+ def update (self , * registries : Registry ) -> Registry :
103109 contents = (registry ._contents for registry in registries )
104110 return attrs .evolve (self , contents = self ._contents .update (* contents ))
105111
106- def with_resources (self , pairs ):
112+ def with_resources (self , pairs ) -> Registry :
107113 contents = self ._contents
108114 for uri , resource in pairs :
109115 assert (
@@ -118,7 +124,7 @@ def with_resources(self, pairs):
118124 contents = contents .set (id , (resource , m ()))
119125 return attrs .evolve (self , contents = contents )
120126
121- def with_anchor (self , anchor : Anchor | DynamicAnchor ):
127+ def with_anchor (self , anchor : Anchor | DynamicAnchor ) -> Registry :
122128 uri_resource , anchors = self ._contents [anchor .uri ]
123129 new = uri_resource , anchors .set (anchor .name , anchor )
124130 return attrs .evolve (self , contents = self ._contents .set (anchor .uri , new ))
@@ -128,7 +134,7 @@ def resolver(self, root) -> Resolver:
128134 registry = self .with_identified_resource (uri = uri , resource = root )
129135 return Resolver (base_uri = uri , registry = registry )
130136
131- def has_not_crawled (self , uri ):
137+ def has_not_crawled (self , uri ) -> bool :
132138 at_uri = self ._contents .get (uri )
133139 return at_uri is None or not at_uri [1 ]
134140
@@ -145,27 +151,23 @@ def lookup(self, ref: str):
145151 else :
146152 uri , fragment = urldefrag (urljoin (self ._base_uri , ref ))
147153 if self ._registry .has_not_crawled (uri ):
148- root , _ = self ._registry .resource_at (self ._base_uri )
154+ root = self ._registry .resource_at (self ._base_uri )
149155 for each in find_subresources (base_uri = self ._base_uri , root = root ):
150156 self ._registry = each .added_to (self ._registry )
151157
152- resource , anchors = self ._registry .resource_at (uri )
153- target = resource
158+ target = self ._registry .resource_at (uri )
154159 if fragment .startswith ("/" ):
155160 segments = unquote (fragment [1 :]).split ("/" )
156161 for segment in segments :
157162 if isinstance (target , Sequence ):
158163 segment = int (segment ) # type: ignore
159164 else :
160165 segment = segment .replace ("~1" , "/" ).replace ("~0" , "~" )
161- target = target [segment ]
166+ target = target [segment ] # type: ignore # this can't be a bool
162167 elif fragment :
163- target = anchors [ fragment ] .resource
168+ target = self . _registry . anchor_at ( uri = uri , name = fragment ) .resource
164169
165- return target , self .with_base_uri (uri )
166-
167- def with_base_uri (self , base_uri ):
168- return attrs .evolve (self , base_uri = base_uri )
170+ return target , attrs .evolve (self , base_uri = uri )
169171
170172 def with_root (self , root ) -> Resolver :
171173 maybe_relative = id_of (root )
@@ -226,7 +228,7 @@ def find_subresources(
226228 if k in resource
227229 for subresource in resource [k ].values ()
228230 )
229- resources .extend ( # TODO: delay finding anchors in subresources...
231+ resources .extend (
230232 (uri , subresource )
231233 for k in SUBRESOURCE_ITEMS
232234 if k in resource
0 commit comments