Skip to content

Commit af5f06c

Browse files
committed
dtype and shape are None for missing operators. Fixes pending work in #385.
1 parent d611101 commit af5f06c

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

src/blosc2/lazyexpr.py

+21-5
Original file line numberDiff line numberDiff line change
@@ -1983,10 +1983,16 @@ def dtype(self):
19831983
):
19841984
# Use the cached dtype
19851985
return self._dtype_
1986+
1987+
# Return None if there is a missing operand (e.g. a removed file on disk)
1988+
if any(v is None for v in self.operands.values()):
1989+
return None
1990+
19861991
operands = {
19871992
key: np.ones(np.ones(len(value.shape), dtype=int), dtype=value.dtype)
19881993
for key, value in self.operands.items()
19891994
}
1995+
19901996
if "contains" in self.expression:
19911997
_out = ne_evaluate(self.expression, local_dict=operands)
19921998
else:
@@ -2019,6 +2025,11 @@ def shape(self):
20192025
):
20202026
# Use the cached shape
20212027
return self._shape_
2028+
2029+
# Return None if there is a missing operand (e.g. a removed file on disk)
2030+
if any(v is None for v in self.operands.values()):
2031+
return None
2032+
20222033
# Operands shape can change, so we always need to recompute this
20232034
_shape, chunks, blocks, fast_path = validate_inputs(self.operands, getattr(self, "_out", None))
20242035
if fast_path:
@@ -3099,11 +3110,16 @@ def _open_lazyarray(array):
30993110
raise TypeError("Error when retrieving the operands")
31003111

31013112
expr = lazyarray["expression"]
3102-
new_expr = LazyExpr._new_expr(expr, operands_dict, guess=True, out=None, where=None)
3103-
# Make the array info available for the user (only available when opened from disk)
3104-
new_expr.array = array
3105-
# We want to expose schunk too, so that .info() can be used on the LazyArray
3106-
new_expr.schunk = array.schunk
3113+
try:
3114+
new_expr = LazyExpr._new_expr(expr, operands_dict, guess=True, out=None, where=None)
3115+
# Make the array info available for the user (only available when opened from disk)
3116+
new_expr.array = array
3117+
# We want to expose schunk too, so that .info() can be used on the LazyArray
3118+
new_expr.schunk = array.schunk
3119+
except RuntimeError:
3120+
# Something unexpected happened. Avoid guessing and return something that
3121+
# can be introspected.
3122+
new_expr = LazyExpr._new_expr(expr, operands_dict, guess=False, out=None, where=None)
31073123
return new_expr
31083124

31093125

tests/ndarray/test_lazyexpr.py

+23
Original file line numberDiff line numberDiff line change
@@ -1307,3 +1307,26 @@ def test_numpy_funcs(array_fixture, func):
13071307
npfunc = getattr(np, func)
13081308
d_numpy = npfunc(((na1**3 + np.sin(na2 * 2)) < na3) & (na2 > 0), axis=0)
13091309
np.testing.assert_equal(d_blosc2, d_numpy)
1310+
1311+
1312+
# Test the LazyExpr when some operands are missing (e.g. removed file)
1313+
def test_missing_operator():
1314+
a = blosc2.arange(10, urlpath="a.b2nd", mode="w")
1315+
b = blosc2.arange(10, urlpath="b.b2nd", mode="w")
1316+
expr = blosc2.lazyexpr("a + b")
1317+
c = expr.save("expr.b2nd", mode="w")
1318+
# Remove the file for operand b
1319+
blosc2.remove_urlpath("b.b2nd")
1320+
# Re-open the lazy expression
1321+
expr2 = blosc2.open("expr.b2nd")
1322+
# Check that some operand is missing
1323+
assert expr2.operands["a"] is not None
1324+
assert expr2.operands["b"] is None
1325+
# Check that the expression is still there, and can be introspected
1326+
assert expr2.expression == "a + b"
1327+
# Check that dtype and shape are None
1328+
assert expr2.dtype is None
1329+
assert expr2.shape is None
1330+
# Clean up
1331+
blosc2.remove_urlpath("a.b2nd")
1332+
blosc2.remove_urlpath("expr.b2nd")

0 commit comments

Comments
 (0)