Skip to content

Commit 5dd21d3

Browse files
committed
Preserve retrieval functions when combining registries.
1 parent ec077b1 commit 5dd21d3

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

referencing/_core.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,15 +326,25 @@ def combine(self, *registries: Registry[D]) -> Registry[D]:
326326
anchors = self._anchors
327327
resources = self._resources
328328
uncrawled = self._uncrawled
329+
retrieve = self._retrieve
329330
for registry in registries:
330331
anchors = anchors.update(registry._anchors) # type: ignore[reportUnknownMemberType] # noqa: E501
331332
resources = resources.update(registry._resources) # type: ignore[reportUnknownMemberType] # noqa: E501
332333
uncrawled = uncrawled.update(registry._uncrawled) # type: ignore[reportUnknownMemberType] # noqa: E501
334+
335+
if registry._retrieve != _fail_to_retrieve:
336+
if registry._retrieve != retrieve != _fail_to_retrieve:
337+
raise ValueError(
338+
"Cannot combine registries with conflicting retrieval "
339+
"functions.",
340+
)
341+
retrieve = registry._retrieve
333342
return evolve(
334343
self,
335344
anchors=anchors,
336345
resources=resources,
337346
uncrawled=uncrawled,
347+
retrieve=retrieve,
338348
)
339349

340350
def resolver(self, base_uri: URI = "") -> Resolver[D]:

referencing/tests/test_core.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,102 @@ def test_combine_with_uncrawled_resources(self):
242242
assert combined != expected
243243
assert combined.crawl() == expected
244244

245+
def test_combine_with_single_retrieve(self):
246+
one = Resource.opaque(contents={})
247+
two = ID_AND_CHILDREN.create_resource({"foo": "bar"})
248+
three = ID_AND_CHILDREN.create_resource({"baz": "quux"})
249+
250+
def retrieve(uri):
251+
pass
252+
253+
first = Registry().with_resource("http://example.com/1", one)
254+
second = Registry(
255+
retrieve=retrieve,
256+
).with_resource("http://example.com/2", two)
257+
third = Registry().with_resource("http://example.com/3", three)
258+
259+
assert first.combine(second, third) == Registry(
260+
retrieve=retrieve,
261+
).with_resources(
262+
[
263+
("http://example.com/1", one),
264+
("http://example.com/2", two),
265+
("http://example.com/3", three),
266+
],
267+
)
268+
assert second.combine(first, third) == Registry(
269+
retrieve=retrieve,
270+
).with_resources(
271+
[
272+
("http://example.com/1", one),
273+
("http://example.com/2", two),
274+
("http://example.com/3", three),
275+
],
276+
)
277+
278+
def test_combine_with_common_retrieve(self):
279+
one = Resource.opaque(contents={})
280+
two = ID_AND_CHILDREN.create_resource({"foo": "bar"})
281+
three = ID_AND_CHILDREN.create_resource({"baz": "quux"})
282+
283+
def retrieve(uri):
284+
pass
285+
286+
first = Registry(retrieve=retrieve).with_resource(
287+
"http://example.com/1",
288+
one,
289+
)
290+
second = Registry(
291+
retrieve=retrieve,
292+
).with_resource("http://example.com/2", two)
293+
third = Registry(retrieve=retrieve).with_resource(
294+
"http://example.com/3",
295+
three,
296+
)
297+
298+
assert first.combine(second, third) == Registry(
299+
retrieve=retrieve,
300+
).with_resources(
301+
[
302+
("http://example.com/1", one),
303+
("http://example.com/2", two),
304+
("http://example.com/3", three),
305+
],
306+
)
307+
assert second.combine(first, third) == Registry(
308+
retrieve=retrieve,
309+
).with_resources(
310+
[
311+
("http://example.com/1", one),
312+
("http://example.com/2", two),
313+
("http://example.com/3", three),
314+
],
315+
)
316+
317+
def test_combine_conflicting_retrieve(self):
318+
one = Resource.opaque(contents={})
319+
two = ID_AND_CHILDREN.create_resource({"foo": "bar"})
320+
three = ID_AND_CHILDREN.create_resource({"baz": "quux"})
321+
322+
def foo_retrieve(uri):
323+
pass
324+
325+
def bar_retrieve(uri):
326+
pass
327+
328+
first = Registry(retrieve=foo_retrieve).with_resource(
329+
"http://example.com/1",
330+
one,
331+
)
332+
second = Registry().with_resource("http://example.com/2", two)
333+
third = Registry(retrieve=bar_retrieve).with_resource(
334+
"http://example.com/3",
335+
three,
336+
)
337+
338+
with pytest.raises(Exception, match="conflict.*retriev"): # noqa: B017
339+
first.combine(second, third)
340+
245341
def test_repr(self):
246342
one = Resource.opaque(contents={})
247343
two = ID_AND_CHILDREN.create_resource({"foo": "bar"})

0 commit comments

Comments
 (0)