@@ -66,6 +66,9 @@ def added_to(self, registry: Registry):
66
66
return registry .with_anchor (anchor = self )
67
67
68
68
69
+ AnchorType = Union [Anchor , DynamicAnchor ]
70
+
71
+
69
72
@frozen
70
73
class IdentifiedResource :
71
74
@@ -82,28 +85,31 @@ def added_to(self, registry: Registry):
82
85
@frozen
83
86
class Registry :
84
87
85
- _contents : PMap [str , tuple [Schema , PMap [str , Schema ]]] = attrs .field (
88
+ _contents : PMap [str , tuple [Schema , PMap [str , AnchorType ]]] = attrs .field (
86
89
default = m (),
87
90
repr = lambda value : f"({ len (value )} entries)" ,
88
91
)
89
92
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 ]
92
98
93
- def with_resource (self , resource ):
99
+ def with_resource (self , resource ) -> Registry :
94
100
uri = id_of (resource )
95
101
if uri is None :
96
102
raise UnidentifiedResource (resource )
97
103
return self .with_identified_resource (uri = uri , resource = resource )
98
104
99
- def with_identified_resource (self , uri , resource ):
105
+ def with_identified_resource (self , uri , resource ) -> Registry :
100
106
return self .with_resources ([(uri , resource )])
101
107
102
- def update (self , * registries : Registry ):
108
+ def update (self , * registries : Registry ) -> Registry :
103
109
contents = (registry ._contents for registry in registries )
104
110
return attrs .evolve (self , contents = self ._contents .update (* contents ))
105
111
106
- def with_resources (self , pairs ):
112
+ def with_resources (self , pairs ) -> Registry :
107
113
contents = self ._contents
108
114
for uri , resource in pairs :
109
115
assert (
@@ -118,7 +124,7 @@ def with_resources(self, pairs):
118
124
contents = contents .set (id , (resource , m ()))
119
125
return attrs .evolve (self , contents = contents )
120
126
121
- def with_anchor (self , anchor : Anchor | DynamicAnchor ):
127
+ def with_anchor (self , anchor : Anchor | DynamicAnchor ) -> Registry :
122
128
uri_resource , anchors = self ._contents [anchor .uri ]
123
129
new = uri_resource , anchors .set (anchor .name , anchor )
124
130
return attrs .evolve (self , contents = self ._contents .set (anchor .uri , new ))
@@ -128,7 +134,7 @@ def resolver(self, root) -> Resolver:
128
134
registry = self .with_identified_resource (uri = uri , resource = root )
129
135
return Resolver (base_uri = uri , registry = registry )
130
136
131
- def has_not_crawled (self , uri ):
137
+ def has_not_crawled (self , uri ) -> bool :
132
138
at_uri = self ._contents .get (uri )
133
139
return at_uri is None or not at_uri [1 ]
134
140
@@ -145,27 +151,23 @@ def lookup(self, ref: str):
145
151
else :
146
152
uri , fragment = urldefrag (urljoin (self ._base_uri , ref ))
147
153
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 )
149
155
for each in find_subresources (base_uri = self ._base_uri , root = root ):
150
156
self ._registry = each .added_to (self ._registry )
151
157
152
- resource , anchors = self ._registry .resource_at (uri )
153
- target = resource
158
+ target = self ._registry .resource_at (uri )
154
159
if fragment .startswith ("/" ):
155
160
segments = unquote (fragment [1 :]).split ("/" )
156
161
for segment in segments :
157
162
if isinstance (target , Sequence ):
158
163
segment = int (segment ) # type: ignore
159
164
else :
160
165
segment = segment .replace ("~1" , "/" ).replace ("~0" , "~" )
161
- target = target [segment ]
166
+ target = target [segment ] # type: ignore # this can't be a bool
162
167
elif fragment :
163
- target = anchors [ fragment ] .resource
168
+ target = self . _registry . anchor_at ( uri = uri , name = fragment ) .resource
164
169
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 )
169
171
170
172
def with_root (self , root ) -> Resolver :
171
173
maybe_relative = id_of (root )
@@ -226,7 +228,7 @@ def find_subresources(
226
228
if k in resource
227
229
for subresource in resource [k ].values ()
228
230
)
229
- resources .extend ( # TODO: delay finding anchors in subresources...
231
+ resources .extend (
230
232
(uri , subresource )
231
233
for k in SUBRESOURCE_ITEMS
232
234
if k in resource
0 commit comments