From b375b6e0df47fa968a8243d3bad25ea9c8fc7ca8 Mon Sep 17 00:00:00 2001 From: Roy Smart Date: Wed, 26 Nov 2025 10:46:19 -0700 Subject: [PATCH 1/3] Fixed a bug where an error was raised where the `item` argument of `__getitem__` or `__setitem__` was a `bool`. --- named_arrays/_functions/functions.py | 6 ++++++ named_arrays/_scalars/scalars.py | 6 ++++++ named_arrays/_scalars/uncertainties/uncertainties.py | 6 ++++++ named_arrays/_vectors/vectors.py | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/named_arrays/_functions/functions.py b/named_arrays/_functions/functions.py index d57dec5..1558e07 100644 --- a/named_arrays/_functions/functions.py +++ b/named_arrays/_functions/functions.py @@ -438,6 +438,9 @@ def _getitem( inputs = array.inputs outputs = array.outputs + if isinstance(item, bool): + item = na.as_named_array(item) + if isinstance(item, na.AbstractArray): if isinstance(item, na.AbstractFunctionArray): if not np.all(item.inputs == array.inputs): @@ -991,6 +994,9 @@ def __setitem__( value: float | u.Quantity | na.FunctionArray, ): + if isinstance(item, bool): + item = na.as_named_array(item) + if isinstance(item, na.AbstractFunctionArray): if not np.all(item.inputs == self.inputs): raise ValueError("boolean advanced index does not have the same inputs as the array") diff --git a/named_arrays/_scalars/scalars.py b/named_arrays/_scalars/scalars.py index 81d723a..cfa77de 100644 --- a/named_arrays/_scalars/scalars.py +++ b/named_arrays/_scalars/scalars.py @@ -393,6 +393,9 @@ def _getitem( item: dict[str, int | slice | AbstractScalarArray] | AbstractScalarArray, ): + if isinstance(item, bool): + item = na.as_named_array(item) + if isinstance(item, AbstractScalarArray): if not set(item.shape).issubset(self.axes): @@ -1016,6 +1019,9 @@ def __setitem__( else: value = ScalarArray(value) + if isinstance(item, bool): + item = na.as_named_array(item) + if isinstance(item, AbstractScalarArray): item = item.explicit diff --git a/named_arrays/_scalars/uncertainties/uncertainties.py b/named_arrays/_scalars/uncertainties/uncertainties.py index 45177c0..fee9c6d 100644 --- a/named_arrays/_scalars/uncertainties/uncertainties.py +++ b/named_arrays/_scalars/uncertainties/uncertainties.py @@ -268,6 +268,9 @@ def _getitem( nominal = na.as_named_array(array.nominal) distribution = na.as_named_array(array.distribution) + if isinstance(item, bool): + item = na.as_named_array(item) + if isinstance(item, na.AbstractArray): item = item.explicit if isinstance(item, AbstractUncertainScalarArray): @@ -649,6 +652,9 @@ def __setitem__( ): shape_self = self.shape + if isinstance(item, bool): + item = na.as_named_array(item) + if isinstance(item, na.AbstractArray): item = item.explicit diff --git a/named_arrays/_vectors/vectors.py b/named_arrays/_vectors/vectors.py index f3c3c40..b5d0e9c 100644 --- a/named_arrays/_vectors/vectors.py +++ b/named_arrays/_vectors/vectors.py @@ -262,6 +262,9 @@ def _getitem( shape_array = array.shape components = array.components + if isinstance(item, bool): + item = na.as_named_array(item) + if isinstance(item, na.AbstractArray): item = item.explicit shape_item = item.shape @@ -610,6 +613,9 @@ def __setitem__( ): components_self = self.components + if isinstance(item, bool): + item = na.as_named_array(item) + if isinstance(item, na.AbstractArray): if isinstance(item, na.AbstractVectorArray): if item.type_abstract == self.type_abstract: From 25bb1c815a2de9810709c3952b50cf7cb69bee75 Mon Sep 17 00:00:00 2001 From: Roy Smart Date: Wed, 26 Nov 2025 23:11:07 -0700 Subject: [PATCH 2/3] testing --- named_arrays/_functions/functions.py | 2 +- named_arrays/_functions/tests/test_functions.py | 6 +++--- named_arrays/_scalars/scalars.py | 6 ++++++ named_arrays/_scalars/tests/test_scalars.py | 2 ++ .../_scalars/uncertainties/tests/test_uncertainties.py | 2 ++ named_arrays/_scalars/uncertainties/uncertainties.py | 2 +- .../_vectors/cartesian/tests/test_vectors_cartesian_2d.py | 2 ++ named_arrays/_vectors/vectors.py | 2 +- 8 files changed, 18 insertions(+), 6 deletions(-) diff --git a/named_arrays/_functions/functions.py b/named_arrays/_functions/functions.py index 1558e07..293b2d8 100644 --- a/named_arrays/_functions/functions.py +++ b/named_arrays/_functions/functions.py @@ -1017,7 +1017,7 @@ def __setitem__( item_inputs[ax] = item_outputs[ax] = item_ax else: raise TypeError( - f"`item` must be an instance of `{dict.__name__}`, or `{na.AbstractFunctionArray.__name__}`, " + f"`item` must be an instance of `bool`, `{dict.__name__}`, or `{na.AbstractFunctionArray.__name__}`, " f"got `{type(item)}`" ) diff --git a/named_arrays/_functions/tests/test_functions.py b/named_arrays/_functions/tests/test_functions.py index c63479e..67278b1 100644 --- a/named_arrays/_functions/tests/test_functions.py +++ b/named_arrays/_functions/tests/test_functions.py @@ -194,6 +194,7 @@ def test_interp_linear_identity( with pytest.raises(NotImplementedError): array.interp_linear(array.indices) + @pytest.mark.parametrize( argnames='item', argvalues=[ @@ -206,6 +207,7 @@ def test_interp_linear_identity( outputs=na.ScalarArrayRange(0, 2, axis='y'), ) ), + True, na.ScalarLinearSpace(0, 1, axis='y', num=_num_y) > 0.5, na.FunctionArray( inputs=na.ScalarLinearSpace(0, 1, axis='y', num=_num_y), @@ -225,9 +227,6 @@ def test_interp_linear_identity( ) ], ) - - - def test__getitem__( self, array: na.AbstractFunctionArray, @@ -947,6 +946,7 @@ class TestFunctionArray( dict(y=slice(None)), dict(y=na.ScalarArrayRange(0, _num_y, axis='y')), dict(x=na.ScalarArrayRange(0, _num_x, axis='x'), y=na.ScalarArrayRange(0, _num_y, axis='y')), + True, na.FunctionArray( inputs=na.ScalarLinearSpace(0, 1, axis='y', num=_num_y), outputs=na.ScalarArray.ones(shape=dict(y=_num_y), dtype=bool), diff --git a/named_arrays/_scalars/scalars.py b/named_arrays/_scalars/scalars.py index cfa77de..107ec7b 100644 --- a/named_arrays/_scalars/scalars.py +++ b/named_arrays/_scalars/scalars.py @@ -1086,6 +1086,12 @@ def __setitem__( self.ndarray_aligned(axes_self)[tuple(index)] = value + else: + raise TypeError( + f"`item` must be an instance of `bool`, `{na.AbstractArray.__name__}`, or {dict.__name__}, " + f"got `{type(item)}`" + ) + @dataclasses.dataclass(eq=False, repr=False) class AbstractImplicitScalarArray( diff --git a/named_arrays/_scalars/tests/test_scalars.py b/named_arrays/_scalars/tests/test_scalars.py index 1c81144..ef81e43 100644 --- a/named_arrays/_scalars/tests/test_scalars.py +++ b/named_arrays/_scalars/tests/test_scalars.py @@ -425,6 +425,7 @@ def test_change_axis_index(self, array: na.ScalarArray, index: int): dict(y=0), dict(y=slice(0,1)), dict(y=na.ScalarArray(np.array([0, 1]), axes=('y', ))), + True, na.ScalarLinearSpace(0, 1, axis='y', num=_num_y) > 0.5, ] ) @@ -1319,6 +1320,7 @@ class TestScalarArray( dict(y=slice(None)), dict(y=na.ScalarArrayRange(0, _num_y, axis='y')), dict(x=na.ScalarArrayRange(0, _num_x, axis='x'), y=na.ScalarArrayRange(0, _num_y, axis='y')), + True, na.ScalarArray.ones(shape=dict(y=_num_y), dtype=bool), ], ) diff --git a/named_arrays/_scalars/uncertainties/tests/test_uncertainties.py b/named_arrays/_scalars/uncertainties/tests/test_uncertainties.py index 4eed968..1ddd593 100644 --- a/named_arrays/_scalars/uncertainties/tests/test_uncertainties.py +++ b/named_arrays/_scalars/uncertainties/tests/test_uncertainties.py @@ -114,6 +114,7 @@ def test_shape_distribution(self, array: na.AbstractUncertainScalarArray): ) ) ), + True, na.ScalarLinearSpace(0, 1, axis='y', num=_num_y) > 0.5, na.UncertainScalarArray( nominal=na.ScalarLinearSpace(0, 1, axis='y', num=_num_y), @@ -795,6 +796,7 @@ class TestUncertainScalarArray( dict(y=slice(None)), dict(y=na.ScalarArrayRange(0, _num_y, axis='y')), dict(x=na.ScalarArrayRange(0, _num_x, axis='x'), y=na.ScalarArrayRange(0, _num_y, axis='y')), + True, na.ScalarArray.ones(shape=dict(y=_num_y), dtype=bool), ], ) diff --git a/named_arrays/_scalars/uncertainties/uncertainties.py b/named_arrays/_scalars/uncertainties/uncertainties.py index fee9c6d..19f55e0 100644 --- a/named_arrays/_scalars/uncertainties/uncertainties.py +++ b/named_arrays/_scalars/uncertainties/uncertainties.py @@ -703,7 +703,7 @@ def __setitem__( else: raise TypeError( - f"`item` must be an instance of `{na.AbstractArray.__name__}` or {dict.__name__}, " + f"`item` must be an instance of `bool`, `{na.AbstractArray.__name__}`, or {dict.__name__}, " f"got `{type(item)}`" ) diff --git a/named_arrays/_vectors/cartesian/tests/test_vectors_cartesian_2d.py b/named_arrays/_vectors/cartesian/tests/test_vectors_cartesian_2d.py index a982d36..e3f136a 100644 --- a/named_arrays/_vectors/cartesian/tests/test_vectors_cartesian_2d.py +++ b/named_arrays/_vectors/cartesian/tests/test_vectors_cartesian_2d.py @@ -108,6 +108,7 @@ def _cartesian2d_items() -> list[na.AbstractArray | dict[str, int, slice, na.Abs ) ) ), + True, na.ScalarLinearSpace(0, 1, axis='y', num=_num_y) > 0.5, na.UniformUncertainScalarArray( nominal=na.ScalarLinearSpace(0, 1, axis='y', num=_num_y), @@ -259,6 +260,7 @@ class TestCartesian2dVectorArray( y=na.ScalarArrayRange(0, _num_y, axis='y'), ) ), + True, na.ScalarArray.ones(shape=dict(y=_num_y), dtype=bool), np.ones_like(na.Cartesian2dVectorArray(), dtype=bool, shape=dict(y=_num_y)), ], diff --git a/named_arrays/_vectors/vectors.py b/named_arrays/_vectors/vectors.py index b5d0e9c..b5cf7e2 100644 --- a/named_arrays/_vectors/vectors.py +++ b/named_arrays/_vectors/vectors.py @@ -668,7 +668,7 @@ def __setitem__( else: raise TypeError( - f"`item` must be an instance of `{na.AbstractArray.__name__}` or {dict.__name__}, " + f"`item` must be an instance of `bool`, `{na.AbstractArray.__name__}`, or {dict.__name__}, " f"got `{type(item)}`" ) From f30cf7870c1b37594299791cabcd90d14f5d85d5 Mon Sep 17 00:00:00 2001 From: Roy Smart Date: Sat, 29 Nov 2025 12:07:10 -0700 Subject: [PATCH 3/3] fixes --- named_arrays/_functions/tests/test_functions.py | 13 +++++-------- named_arrays/_scalars/tests/test_scalars.py | 5 ++++- .../uncertainties/tests/test_uncertainties.py | 5 ++++- named_arrays/_vectors/tests/test_vectors.py | 3 +++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/named_arrays/_functions/tests/test_functions.py b/named_arrays/_functions/tests/test_functions.py index 67278b1..4b20c7f 100644 --- a/named_arrays/_functions/tests/test_functions.py +++ b/named_arrays/_functions/tests/test_functions.py @@ -239,6 +239,9 @@ def test__getitem__( array[item] return + if isinstance(item, bool): + item_outputs = item_inputs = item + if isinstance(item, na.AbstractArray): item = item.explicit if isinstance(item, na.AbstractFunctionArray): @@ -260,7 +263,7 @@ def test__getitem__( item_outputs[ax] = item_ax.outputs else: if ax in array.axes_center: - #can't assume center ax is in both outputs and inputs + # can't assume center ax is in both outputs and inputs if ax in array.inputs.shape: item_inputs[ax] = item_ax if ax in array.outputs.shape: @@ -408,7 +411,6 @@ def test_ufunc_binary( assert np.all(result[i] == result_out[i]) assert result_out[i] is out[i] - class TestMatmul( named_arrays.tests.test_core.AbstractTestAbstractArray.TestMatmul ): @@ -703,7 +705,6 @@ def test_arg_reduction_functions( assert np.all(result.outputs == outputs_expected) - class TestFFTLikeFunctions( named_arrays.tests.test_core.AbstractTestAbstractArray.TestArrayFunctions.TestFFTLikeFunctions, ): @@ -863,7 +864,7 @@ def test_pcolormesh( components = list(array.inputs.components.keys())[:2] - #probably a smarter way to deal with plotting broadcasting during testing + # probably a smarter way to deal with plotting broadcasting during testing if len(array.axes) > 2: array = array[dict(z=0)] @@ -984,7 +985,6 @@ class TestMatmul( pass - @pytest.mark.parametrize("type_array", [na.FunctionArray]) class TestFunctionArrayCreation( named_arrays.tests.test_core.AbstractTestAbstractExplicitArrayCreation, @@ -1125,6 +1125,3 @@ class TestMatmul( AbstractTestAbstractFunctionArray.TestMatmul ): pass - - - diff --git a/named_arrays/_scalars/tests/test_scalars.py b/named_arrays/_scalars/tests/test_scalars.py index ef81e43..3c67882 100644 --- a/named_arrays/_scalars/tests/test_scalars.py +++ b/named_arrays/_scalars/tests/test_scalars.py @@ -449,7 +449,10 @@ def test__getitem__( else: if array.shape: result = array[item] - item_expected = (Ellipsis, item.ndarray) + if isinstance(item, bool): + item_expected = item + else: + item_expected = (Ellipsis, item.ndarray) else: with pytest.raises(ValueError): array[item] diff --git a/named_arrays/_scalars/uncertainties/tests/test_uncertainties.py b/named_arrays/_scalars/uncertainties/tests/test_uncertainties.py index 1ddd593..a5f01e8 100644 --- a/named_arrays/_scalars/uncertainties/tests/test_uncertainties.py +++ b/named_arrays/_scalars/uncertainties/tests/test_uncertainties.py @@ -133,7 +133,10 @@ def test__getitem__( ): super().test__getitem__(array=array, item=item) - if isinstance(item, na.AbstractArray): + if isinstance(item, bool): + item_nominal = item_distribution = item + + elif isinstance(item, na.AbstractArray): if not set(item.shape).issubset(array.shape_distribution): with pytest.raises(ValueError): diff --git a/named_arrays/_vectors/tests/test_vectors.py b/named_arrays/_vectors/tests/test_vectors.py index 79d90f2..fc24b64 100644 --- a/named_arrays/_vectors/tests/test_vectors.py +++ b/named_arrays/_vectors/tests/test_vectors.py @@ -121,6 +121,9 @@ def test__getitem__( for c in components: components_item[c][ax] = components_item_ax[c] + elif isinstance(item, bool): + components_item = array.type_explicit.from_scalar(item, like=array).components + else: if not array.shape: with pytest.raises(ValueError):