Skip to content

fix(storage): MemoryStore.list_prefix uses directory-boundary semantics#3842

Open
NIK-TIGER-BILL wants to merge 2 commits intozarr-developers:mainfrom
NIK-TIGER-BILL:fix/memory-store-list-prefix-path-semantics
Open

fix(storage): MemoryStore.list_prefix uses directory-boundary semantics#3842
NIK-TIGER-BILL wants to merge 2 commits intozarr-developers:mainfrom
NIK-TIGER-BILL:fix/memory-store-list-prefix-path-semantics

Conversation

@NIK-TIGER-BILL
Copy link

Summary

Fixes #3773

MemoryStore.list_prefix("0") was returning keys from sibling paths (e.g. "0_c/zarr.json") because it used a raw str.startswith check. LocalStore correctly uses filesystem directory semantics and only returns items under the "0/" directory.

This PR makes MemoryStore.list_prefix consistent with LocalStore by normalising the prefix to always end with / before matching.

Root Cause

# Before (buggy)
if key.startswith(prefix):  # prefix="0" matches "0_c/zarr.json" ❌

# After (fixed)
prefix = prefix.rstrip("/") + "/"  # prefix="0/"
if key.startswith(prefix):  # "0/" does NOT match "0_c/zarr.json" ✅

Repro

import asyncio, zarr

async def list_prefix(store, prefix):
    return sorted([k async for k in store.list_prefix(prefix)])

def run(store):
    root = zarr.open_group(store, mode="w")
    root.create_group("0")
    root.create_array("0_c", shape=(1,), dtype="i4")
    print(asyncio.run(list_prefix(store, "0")))

print("Before fix - MemoryStore:")  # [0/zarr.json, 0_c/zarr.json] ❌
run(zarr.storage.MemoryStore())
print("After fix - MemoryStore:")   # [0/zarr.json] ✅

Changes

  • src/zarr/storage/_memory.py: list_prefix now normalises the prefix to end with /
  • tests/test_store/test_memory.py: regression test test_list_prefix_path_boundary

Closes #3773

@github-actions github-actions bot added the needs release notes Automatically applied to PRs which haven't added release notes label Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs release notes Automatically applied to PRs which haven't added release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Divergent behavior of memory store and localstore list prefix

1 participant