Skip to content

Commit 3a57296

Browse files
committed
Use default reopen mode for persisted lazyexpr urlpath operands
1 parent eeb8650 commit 3a57296

5 files changed

Lines changed: 17 additions & 43 deletions

File tree

src/blosc2/proxy.py

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,6 @@ class Proxy(blosc2.Operand):
192192
193193
This can be used to cache chunks of a regular data container which follows the
194194
:ref:`ProxySource` or :ref:`ProxyNDSource` interfaces.
195-
196-
If a persisted proxy is reopened in read mode, lazy cache fills still need to
197-
update the local cache. In that case the cache file is reopened internally
198-
in append mode on demand when :meth:`fetch`, :meth:`afetch`, or
199-
:meth:`__getitem__` needs to populate missing chunks.
200195
"""
201196

202197
def __init__(
@@ -214,9 +209,6 @@ def __init__(
214209
mode: str, optional
215210
"a" means read/write (create if it doesn't exist); "w" means create
216211
(overwrite if it exists). Default is "a".
217-
When a persisted proxy is reopened through :func:`blosc2.open` with
218-
``mode="r"``, later lazy cache fills may reopen the cache file
219-
internally in append mode so missing chunks can be written locally.
220212
kwargs: dict, optional
221213
Keyword arguments supported:
222214
@@ -274,14 +266,6 @@ def __init__(
274266
for key in vlmeta:
275267
self._schunk_cache.vlmeta[key] = vlmeta[key]
276268

277-
def _ensure_writable_cache(self) -> None:
278-
"""Reopen a persisted cache writable when lazy fetch needs to fill chunks."""
279-
cache_urlpath = getattr(self._schunk_cache, "urlpath", None)
280-
if cache_urlpath is None or getattr(self._schunk_cache, "mode", None) != "r":
281-
return
282-
self._cache = blosc2.blosc2_ext.open(cache_urlpath, "a", 0)
283-
self._schunk_cache = getattr(self._cache, "schunk", self._cache)
284-
285269
def fetch(self, item: slice | list[slice] | None = ()) -> blosc2.NDArray | blosc2.schunk.SChunk:
286270
"""
287271
Get the container used as cache with the requested data updated.
@@ -297,13 +281,6 @@ def fetch(self, item: slice | list[slice] | None = ()) -> blosc2.NDArray | blosc
297281
out: :ref:`NDArray` or :ref:`SChunk`
298282
The local container used to cache the already requested data.
299283
300-
Notes
301-
-----
302-
If the proxy cache was reopened read-only from disk, this method may
303-
reopen that cache internally in append mode before filling missing
304-
chunks. This preserves the logical read-only open of the proxy source
305-
while still allowing the local cache to be populated lazily.
306-
307284
Examples
308285
--------
309286
>>> import numpy as np
@@ -317,7 +294,6 @@ def fetch(self, item: slice | list[slice] | None = ()) -> blosc2.NDArray | blosc
317294
[2 3]
318295
[4 5]]
319296
"""
320-
self._ensure_writable_cache()
321297
if item == ():
322298
# Full realization
323299
for info in self._schunk_cache.iterchunks_info():
@@ -353,9 +329,6 @@ async def afetch(self, item: slice | list[slice] | None = ()) -> blosc2.NDArray
353329
-----
354330
This method is only available if the :ref:`ProxySource` or :ref:`ProxyNDSource`
355331
have an async `aget_chunk` method.
356-
If the proxy cache was reopened read-only from disk, this method may
357-
reopen that cache internally in append mode before filling missing
358-
chunks.
359332
360333
Examples
361334
--------
@@ -413,7 +386,6 @@ async def afetch(self, item: slice | list[slice] | None = ()) -> blosc2.NDArray
413386
"""
414387
if not callable(getattr(self.src, "aget_chunk", None)):
415388
raise NotImplementedError("afetch is only available if the source has an aget_chunk method")
416-
self._ensure_writable_cache()
417389
if item == ():
418390
# Full realization
419391
for info in self._schunk_cache.iterchunks_info():

src/blosc2/ref.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def open(self):
118118
import blosc2
119119

120120
if self.kind == "urlpath":
121-
return blosc2.open(self.urlpath, mode="r")
121+
return blosc2.open(self.urlpath)
122122
if self.kind == "dictstore_key":
123123
return blosc2.DictStore(self.urlpath, mode="r")[self.key]
124124
if self.kind == "c2array":

src/blosc2/schunk.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,9 +1721,6 @@ def open(
17211721
it will return the Python-Blosc2 container used to cache the data which
17221722
can be a :ref:`SChunk` or a :ref:`NDArray` and may not have all the data
17231723
initialized (e.g. if the user has not accessed to it yet).
1724-
When such a persisted proxy is opened with ``mode="r"``, later lazy cache
1725-
fills may reopen the local cache internally in append mode so missing
1726-
chunks can still be written.
17271724
17281725
* When opening a :ref:`LazyExpr` keep in mind the note above regarding operands.
17291726

tests/ndarray/test_lazyexpr.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,22 @@ def test_save_dictstore_operands(tmp_path):
17521752
np.testing.assert_array_equal(restored[:], expected)
17531753

17541754

1755+
def test_save_proxy_operands_reopen_default_mode(tmp_path):
1756+
src_path = tmp_path / "src.b2nd"
1757+
proxy_path = tmp_path / "proxy.b2nd"
1758+
expr_path = tmp_path / "expr.b2nd"
1759+
1760+
src = blosc2.asarray(np.arange(10, dtype=np.int64), urlpath=str(src_path), mode="w")
1761+
proxy = blosc2.Proxy(src, urlpath=str(proxy_path), mode="w")
1762+
expr = proxy + proxy
1763+
expr.save(str(expr_path))
1764+
1765+
restored = blosc2.open(str(expr_path))
1766+
1767+
assert isinstance(restored, blosc2.LazyExpr)
1768+
np.testing.assert_array_equal(restored[:], np.arange(10, dtype=np.int64) * 2)
1769+
1770+
17551771
# Test the chaining of multiple lazy expressions
17561772
def test_chain_expressions():
17571773
N = 1_000

tests/ndarray/test_proxy.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,6 @@ def test_open(urlpath, shape, chunks, blocks, slices, dtype):
105105
blosc2.remove_urlpath(proxy_urlpath)
106106

107107

108-
def test_open_read_mode_allows_proxy_cache_fill(tmp_path):
109-
src_urlpath = str(tmp_path / "src.b2nd")
110-
proxy_urlpath = str(tmp_path / "proxy.b2nd")
111-
112-
a = blosc2.asarray(np.arange(25, dtype=np.int64).reshape(5, 5), urlpath=src_urlpath, mode="w")
113-
_ = blosc2.Proxy(a, urlpath=proxy_urlpath, mode="w")
114-
115-
proxy = blosc2.open(proxy_urlpath, mode="r")
116-
np.testing.assert_array_equal(proxy[:], a[:])
117-
118-
119108
# Test the ProxyNDSources interface
120109
@pytest.mark.parametrize(
121110
("shape", "chunks", "blocks"),

0 commit comments

Comments
 (0)