Skip to content

Commit c0b303c

Browse files
author
Cipher
committed
fix: initialize _lock attribute in ZipStore (#3588)
ZipStore._lock was initialized in _sync_open() but accessed by methods (get, set, exists, etc.) that can be called before the store is opened. This caused AttributeError: 'ZipStore' object has no attribute '_lock'. Move _lock initialization to __init__ so it is always available after instantiation, regardless of whether the store has been opened yet. Fixes #3588
1 parent 1cb1cce commit c0b303c

2 files changed

Lines changed: 13 additions & 2 deletions

File tree

src/zarr/storage/_zip.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,12 @@ def __init__(
8787
self._zmode = mode
8888
self.compression = compression
8989
self.allowZip64 = allowZip64
90+
self._lock = threading.RLock()
9091

9192
def _sync_open(self) -> None:
9293
if self._is_open:
9394
raise ValueError("store is already open")
9495

95-
self._lock = threading.RLock()
96-
9796
self._zf = zipfile.ZipFile(
9897
self.path,
9998
mode=self._zmode,

tests/test_store/test_zip.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,15 @@ async def test_move(self, tmp_path: Path) -> None:
152152
assert destination.exists()
153153
assert not origin.exists()
154154
assert np.array_equal(array[...], np.arange(10))
155+
156+
def test_lock_initialized_before_open(self, store_kwargs: dict[str, Any]) -> None:
157+
"""Regression test for https://github.com/zarr-developers/zarr-python/issues/3588.
158+
159+
ZipStore._lock must be available immediately after __init__, before _open() is called,
160+
so that operations like get/set/exists can use it even on non-opened stores.
161+
"""
162+
import threading
163+
164+
store = self.store_cls(**store_kwargs)
165+
assert hasattr(store, "_lock"), "ZipStore._lock must be initialized in __init__"
166+
assert isinstance(store._lock, type(threading.RLock())), "_lock must be an RLock"

0 commit comments

Comments
 (0)