|
14 | 14 | from zarr.core.buffer import Buffer, BufferPrototype |
15 | 15 | from zarr.core.common import AccessModeLiteral, BytesLike |
16 | 16 |
|
17 | | -__all__ = ["Store", "AccessMode", "ByteGetter", "ByteSetter", "set_or_delete"] |
| 17 | +__all__ = ["AccessMode", "ByteGetter", "ByteSetter", "Store", "set_or_delete"] |
18 | 18 |
|
19 | 19 | ByteRangeRequest: TypeAlias = tuple[int | None, int | None] |
20 | 20 |
|
@@ -99,6 +99,31 @@ async def empty(self) -> bool: ... |
99 | 99 | @abstractmethod |
100 | 100 | async def clear(self) -> None: ... |
101 | 101 |
|
| 102 | + @abstractmethod |
| 103 | + def with_mode(self, mode: AccessModeLiteral) -> Self: |
| 104 | + """ |
| 105 | + Return a new store of the same type pointing to the same location with a new mode. |
| 106 | +
|
| 107 | + The returned Store is not automatically opened. Call :meth:`Store.open` before |
| 108 | + using. |
| 109 | +
|
| 110 | + Parameters |
| 111 | + ---------- |
| 112 | + mode: AccessModeLiteral |
| 113 | + The new mode to use. |
| 114 | +
|
| 115 | + Returns |
| 116 | + ------- |
| 117 | + store: |
| 118 | + A new store of the same type with the new mode. |
| 119 | +
|
| 120 | + Examples |
| 121 | + -------- |
| 122 | + >>> writer = zarr.store.MemoryStore(mode="w") |
| 123 | + >>> reader = writer.with_mode("r") |
| 124 | + """ |
| 125 | + ... |
| 126 | + |
102 | 127 | @property |
103 | 128 | def mode(self) -> AccessMode: |
104 | 129 | """Access mode of the store.""" |
@@ -183,6 +208,22 @@ async def set(self, key: str, value: Buffer) -> None: |
183 | 208 | """ |
184 | 209 | ... |
185 | 210 |
|
| 211 | + async def set_if_not_exists(self, key: str, value: Buffer) -> None: |
| 212 | + """ |
| 213 | + Store a key to ``value`` if the key is not already present. |
| 214 | +
|
| 215 | + Parameters |
| 216 | + ----------- |
| 217 | + key : str |
| 218 | + value : Buffer |
| 219 | + """ |
| 220 | + # Note for implementers: the default implementation provided here |
| 221 | + # is not safe for concurrent writers. There's a race condition between |
| 222 | + # the `exists` check and the `set` where another writer could set some |
| 223 | + # value at `key` or delete `key`. |
| 224 | + if not await self.exists(key): |
| 225 | + await self.set(key, value) |
| 226 | + |
186 | 227 | async def _set_many(self, values: Iterable[tuple[str, Buffer]]) -> None: |
187 | 228 | """ |
188 | 229 | Insert multiple (key, value) pairs into storage. |
@@ -315,6 +356,8 @@ async def set(self, value: Buffer, byte_range: ByteRangeRequest | None = None) - |
315 | 356 |
|
316 | 357 | async def delete(self) -> None: ... |
317 | 358 |
|
| 359 | + async def set_if_not_exists(self, default: Buffer) -> None: ... |
| 360 | + |
318 | 361 |
|
319 | 362 | async def set_or_delete(byte_setter: ByteSetter, value: Buffer | None) -> None: |
320 | 363 | if value is None: |
|
0 commit comments