diff --git a/changes/4161.bugfix.md b/changes/4161.bugfix.md new file mode 100644 index 0000000000..98fb052825 --- /dev/null +++ b/changes/4161.bugfix.md @@ -0,0 +1 @@ +Listing the members of a group no longer emits a `ZarrUserWarning` for store objects that are not part of the Zarr hierarchy (such as the temporary `.partial` files created while a write is in progress); these objects are now skipped silently. diff --git a/src/zarr/core/group.py b/src/zarr/core/group.py index 7792fa58de..29d802df8e 100644 --- a/src/zarr/core/group.py +++ b/src/zarr/core/group.py @@ -3602,15 +3602,11 @@ async def _iter_members( for fetched_node_coro in asyncio.as_completed(node_tasks): try: fetched_node = await fetched_node_coro - except KeyError as e: + except KeyError: # keyerror is raised when `key` names an object (in the object storage sense), # as opposed to a prefix, in the store under the prefix associated with this group # in which case `key` cannot be the name of a sub-array or sub-group. - warnings.warn( - f"Object at {e.args[0]} is not recognized as a component of a Zarr hierarchy.", - ZarrUserWarning, - stacklevel=1, - ) + # Such objects (e.g. temporary files from an in-progress write) are skipped silently. continue match fetched_node: case AsyncArray() | AsyncGroup(): diff --git a/tests/test_group.py b/tests/test_group.py index 6976ef536c..ea02f7a5c2 100644 --- a/tests/test_group.py +++ b/tests/test_group.py @@ -217,38 +217,42 @@ def test_group_members(store: Store, zarr_format: ZarrFormat, consolidated_metad ) ) - # this warning shows up when extra objects show up in the hierarchy - warn_context = pytest.warns( - ZarrUserWarning, - match=r"(?:Object at .* is not recognized as a component of a Zarr hierarchy.)|(?:Consolidated metadata is currently not part in the Zarr format 3 specification.)", - ) if consolidated_metadata: + consolidate_warn_context = ( + pytest.warns( + ZarrUserWarning, + match="Consolidated metadata is currently not part in the Zarr format 3 specification.", + ) + if zarr_format == 3 + else contextlib.nullcontext() + ) if isinstance(store, ZipStore): - with warn_context: + with consolidate_warn_context: with pytest.warns(UserWarning, match="Duplicate name: "): zarr.consolidate_metadata(store=store, zarr_format=zarr_format) else: - with warn_context: + with consolidate_warn_context: zarr.consolidate_metadata(store=store, zarr_format=zarr_format) - # now that we've consolidated the store, we shouldn't get the warnings from the unrecognized objects anymore - # we use a nullcontext to handle these cases - warn_context = contextlib.nullcontext() group = zarr.open_consolidated(store=store, zarr_format=zarr_format) - with warn_context: + # extra objects in the hierarchy are skipped without warning + with warnings.catch_warnings(): + warnings.simplefilter("error", ZarrUserWarning) members_observed = group.members() # members are not guaranteed to be ordered, so sort before comparing assert sorted(dict(members_observed)) == sorted(members_expected) # partial - with warn_context: + with warnings.catch_warnings(): + warnings.simplefilter("error", ZarrUserWarning) members_observed = group.members(max_depth=1) members_expected["subgroup/subsubgroup"] = subsubgroup # members are not guaranteed to be ordered, so sort before comparing assert sorted(dict(members_observed)) == sorted(members_expected) # total - with warn_context: + with warnings.catch_warnings(): + warnings.simplefilter("error", ZarrUserWarning) members_observed = group.members(max_depth=None) members_expected["subgroup/subsubgroup/subsubsubgroup"] = subsubsubgroup # members are not guaranteed to be ordered, so sort before comparing diff --git a/tests/test_metadata/test_consolidated.py b/tests/test_metadata/test_consolidated.py index cd0fd92d74..685c481e77 100644 --- a/tests/test_metadata/test_consolidated.py +++ b/tests/test_metadata/test_consolidated.py @@ -747,8 +747,7 @@ async def test_use_consolidated_for_children_members( # Now according to the consolidated metadata, "a" has children ["b"] # but according to the unconsolidated metadata, "a" has children ["b", "c"] group = await zarr.api.asynchronous.open_group(store=memory_store, path="a") - with pytest.warns(ZarrUserWarning, match="Object at 'c' not found"): - result = sorted([x[0] async for x in group.members(max_depth=None)]) + result = sorted([x[0] async for x in group.members(max_depth=None)]) expected = ["b"] assert result == expected