From f89a3d54c64d48a75b7ae391508f4965210e77bf Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sat, 4 Jan 2025 19:48:25 +0000
Subject: [PATCH 01/49] add pint's numpy tests

---
 tests/test_array.py | 1528 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1528 insertions(+)
 create mode 100644 tests/test_array.py

diff --git a/tests/test_array.py b/tests/test_array.py
new file mode 100644
index 0000000..4fac87d
--- /dev/null
+++ b/tests/test_array.py
@@ -0,0 +1,1528 @@
+from __future__ import annotations
+
+import copy
+import operator as op
+import pickle
+import warnings
+
+import pytest
+
+from pint import DimensionalityError, OffsetUnitCalculusError, UnitStrippedWarning
+# from pint.compat import np
+from pint.testsuite import helpers
+from pint.testsuite.test_umath import TestUFuncs
+
+import pint_array; 
+import numpy as np; 
+pnp = pint_array.pint_namespace(np); 
+from pint import UnitRegistry; 
+ureg = UnitRegistry()
+
+# @helpers.requires_numpy
+class TestNumpyMethods:
+    @classmethod
+    def setup_class(cls):
+        from pint import _DEFAULT_REGISTRY
+
+        cls.ureg = _DEFAULT_REGISTRY
+        cls.Q_ = cls.ureg.Quantity
+
+    @classmethod
+    def teardown_class(cls):
+        cls.ureg = None
+        cls.Q_ = None
+
+    @property
+    def q(self):
+        return [[1, 2], [3, 4]] * self.ureg.m
+
+    @property
+    def q_scalar(self):
+        return np.array(5) * self.ureg.m
+
+    @property
+    def q_nan(self):
+        return [[1, 2], [3, pnp.nan]] * self.ureg.m
+
+    @property
+    def q_zero_or_nan(self):
+        return [[0, 0], [0, pnp.nan]] * self.ureg.m
+
+    @property
+    def q_temperature(self):
+        return self.Q_([[1, 2], [3, 4]], self.ureg.degC)
+
+    def assertNDArrayEqual(self, actual, desired):
+        # Assert that the given arrays are equal, and are not Quantities
+        pnp.testing.assert_array_equal(actual, desired)
+        assert not isinstance(actual, self.Q_)
+        assert not isinstance(desired, self.Q_)
+
+
+class TestNumpyArrayCreation(TestNumpyMethods):
+    # https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html
+
+    # @helpers.requires_array_function_protocol()
+    def test_ones_like(self):
+        self.assertNDArrayEqual(pnp.ones_like(self.q), np.array([[1, 1], [1, 1]]))
+
+    # @helpers.requires_array_function_protocol()
+    def test_zeros_like(self):
+        self.assertNDArrayEqual(pnp.zeros_like(self.q), np.array([[0, 0], [0, 0]]))
+
+    # @helpers.requires_array_function_protocol()
+    def test_empty_like(self):
+        ret = pnp.empty_like(self.q)
+        assert ret.shape == (2, 2)
+        assert isinstance(ret, pnp.ndarray)
+
+    # @helpers.requires_array_function_protocol()
+    def test_full_like(self):
+        helpers.assert_quantity_equal(
+            pnp.full_like(self.q, self.Q_(0, self.ureg.degC)),
+            self.Q_([[0, 0], [0, 0]], self.ureg.degC),
+        )
+        self.assertNDArrayEqual(pnp.full_like(self.q, 2), np.array([[2, 2], [2, 2]]))
+
+
+class TestNumpyArrayManipulation(TestNumpyMethods):
+    # TODO
+    # https://www.numpy.org/devdocs/reference/routines.array-manipulation.html
+    # copyto
+    # broadcast
+    # asarray	asanyarray	asmatrix	asfarray	asfortranarray	ascontiguousarray	asarray_chkfinite	asscalar	require
+
+    # Changing array shape
+
+    def test_flatten(self):
+        helpers.assert_quantity_equal(self.q.flatten(), [1, 2, 3, 4] * self.ureg.m)
+
+    def test_flat(self):
+        for q, v in zip(self.q.flat, [1, 2, 3, 4]):
+            assert q == v * self.ureg.m
+
+    def test_reshape(self):
+        helpers.assert_quantity_equal(
+            self.q.reshape([1, 4]), [[1, 2, 3, 4]] * self.ureg.m
+        )
+
+    def test_ravel(self):
+        helpers.assert_quantity_equal(self.q.ravel(), [1, 2, 3, 4] * self.ureg.m)
+
+    # @helpers.requires_array_function_protocol()
+    def test_ravel_numpy_func(self):
+        helpers.assert_quantity_equal(pnp.ravel(self.q), [1, 2, 3, 4] * self.ureg.m)
+
+    # Transpose-like operations
+
+    # @helpers.requires_array_function_protocol()
+    def test_moveaxis(self):
+        helpers.assert_quantity_equal(
+            pnp.moveaxis(self.q, 1, 0), np.array([[1, 2], [3, 4]]).T * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_rollaxis(self):
+        helpers.assert_quantity_equal(
+            pnp.rollaxis(self.q, 1), np.array([[1, 2], [3, 4]]).T * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_swapaxes(self):
+        helpers.assert_quantity_equal(
+            pnp.swapaxes(self.q, 1, 0), np.array([[1, 2], [3, 4]]).T * self.ureg.m
+        )
+
+    def test_transpose(self):
+        helpers.assert_quantity_equal(
+            self.q.transpose(), [[1, 3], [2, 4]] * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_transpose_numpy_func(self):
+        helpers.assert_quantity_equal(
+            pnp.transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_flip_numpy_func(self):
+        helpers.assert_quantity_equal(
+            pnp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
+        )
+
+    # Changing number of dimensions
+
+    # @helpers.requires_array_function_protocol()
+    def test_atleast_1d(self):
+        actual = pnp.atleast_1d(self.Q_(0, self.ureg.degC), self.q.flatten())
+        expected = (self.Q_(np.array([0]), self.ureg.degC), self.q.flatten())
+        for ind_actual, ind_expected in zip(actual, expected):
+            helpers.assert_quantity_equal(ind_actual, ind_expected)
+        helpers.assert_quantity_equal(pnp.atleast_1d(self.q), self.q)
+
+    # @helpers.requires_array_function_protocol()
+    def test_atleast_2d(self):
+        actual = pnp.atleast_2d(self.Q_(0, self.ureg.degC), self.q.flatten())
+        expected = (
+            self.Q_(np.array([[0]]), self.ureg.degC),
+            np.array([[1, 2, 3, 4]]) * self.ureg.m,
+        )
+        for ind_actual, ind_expected in zip(actual, expected):
+            helpers.assert_quantity_equal(ind_actual, ind_expected)
+        helpers.assert_quantity_equal(pnp.atleast_2d(self.q), self.q)
+
+    # @helpers.requires_array_function_protocol()
+    def test_atleast_3d(self):
+        actual = pnp.atleast_3d(self.Q_(0, self.ureg.degC), self.q.flatten())
+        expected = (
+            self.Q_(np.array([[[0]]]), self.ureg.degC),
+            np.array([[[1], [2], [3], [4]]]) * self.ureg.m,
+        )
+        for ind_actual, ind_expected in zip(actual, expected):
+            helpers.assert_quantity_equal(ind_actual, ind_expected)
+        helpers.assert_quantity_equal(
+            pnp.atleast_3d(self.q), np.array([[[1], [2]], [[3], [4]]]) * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_broadcast_to(self):
+        helpers.assert_quantity_equal(
+            pnp.broadcast_to(self.q[:, 1], (2, 2)),
+            np.array([[2, 4], [2, 4]]) * self.ureg.m,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_expand_dims(self):
+        helpers.assert_quantity_equal(
+            pnp.expand_dims(self.q, 0), np.array([[[1, 2], [3, 4]]]) * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_squeeze(self):
+        helpers.assert_quantity_equal(pnp.squeeze(self.q), self.q)
+        helpers.assert_quantity_equal(
+            self.q.reshape([1, 4]).squeeze(), [1, 2, 3, 4] * self.ureg.m
+        )
+
+    # Changing number of dimensions
+    # Joining arrays
+    # @helpers.requires_array_function_protocol()
+    def test_concat_stack(self, subtests):
+        for func in (pnp.concatenate, pnp.stack, pnp.hstack, pnp.vstack, pnp.dstack):
+            with subtests.test(func=func):
+                helpers.assert_quantity_equal(
+                    func([self.q] * 2), self.Q_(func([self.q.m] * 2), self.ureg.m)
+                )
+                # One or more of the args is a bare array full of zeros or NaNs
+                helpers.assert_quantity_equal(
+                    func([self.q_zero_or_nan.m, self.q]),
+                    self.Q_(func([self.q_zero_or_nan.m, self.q.m]), self.ureg.m),
+                )
+                # One or more of the args is a bare array with at least one non-zero,
+                # non-NaN element
+                nz = self.q_zero_or_nan
+                nz.m[0, 0] = 1
+                with pytest.raises(DimensionalityError):
+                    func([nz.m, self.q])
+
+    # @helpers.requires_array_function_protocol()
+    def test_block_column_stack(self, subtests):
+        for func in (pnp.block, pnp.column_stack):
+            with subtests.test(func=func):
+                helpers.assert_quantity_equal(
+                    func([self.q[:, 0], self.q[:, 1]]),
+                    self.Q_(func([self.q[:, 0].m, self.q[:, 1].m]), self.ureg.m),
+                )
+
+                # One or more of the args is a bare array full of zeros or NaNs
+                helpers.assert_quantity_equal(
+                    func(
+                        [
+                            self.q_zero_or_nan[:, 0].m,
+                            self.q[:, 0],
+                            self.q_zero_or_nan[:, 1].m,
+                        ]
+                    ),
+                    self.Q_(
+                        func(
+                            [
+                                self.q_zero_or_nan[:, 0].m,
+                                self.q[:, 0].m,
+                                self.q_zero_or_nan[:, 1].m,
+                            ]
+                        ),
+                        self.ureg.m,
+                    ),
+                )
+                # One or more of the args is a bare array with at least one non-zero,
+                # non-NaN element
+                nz = self.q_zero_or_nan
+                nz.m[0, 0] = 1
+                with pytest.raises(DimensionalityError):
+                    func([nz[:, 0].m, self.q[:, 0]])
+
+    # @helpers.requires_array_function_protocol()
+    def test_append(self):
+        helpers.assert_quantity_equal(
+            pnp.append(self.q, [[0, 0]] * self.ureg.m, axis=0),
+            [[1, 2], [3, 4], [0, 0]] * self.ureg.m,
+        )
+
+    def test_astype(self):
+        actual = self.q.astype(pnp.float32)
+        expected = self.Q_(np.array([[1.0, 2.0], [3.0, 4.0]], dtype=pnp.float32), "m")
+        helpers.assert_quantity_equal(actual, expected)
+        assert actual.m.dtype == expected.m.dtype
+
+    def test_item(self):
+        helpers.assert_quantity_equal(self.Q_([[0]], "m").item(), 0 * self.ureg.m)
+
+    def test_broadcast_arrays(self):
+        x = self.Q_(np.array([[1, 2, 3]]), "m")
+        y = self.Q_(np.array([[4], [5]]), "nm")
+        result = pnp.broadcast_arrays(x, y)
+        expected = self.Q_(
+            [
+                [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]],
+                [[4e-09, 4e-09, 4e-09], [5e-09, 5e-09, 5e-09]],
+            ],
+            "m",
+        )
+        helpers.assert_quantity_equal(result, expected)
+
+        result = pnp.broadcast_arrays(x, y, subok=True)
+        helpers.assert_quantity_equal(result, expected)
+
+    def test_roll(self):
+        helpers.assert_quantity_equal(
+            pnp.roll(self.q, 1), [[4, 1], [2, 3]] * self.ureg.m
+        )
+
+
+class TestNumpyMathematicalFunctions(TestNumpyMethods):
+    # https://www.numpy.org/devdocs/reference/routines.math.html
+    # Trigonometric functions
+    # @helpers.requires_array_function_protocol()
+    def test_unwrap(self):
+        helpers.assert_quantity_equal(
+            pnp.unwrap([0, 3 * pnp.pi] * self.ureg.radians), [0, pnp.pi]
+        )
+        helpers.assert_quantity_equal(
+            pnp.unwrap([0, 540] * self.ureg.deg), [0, 180] * self.ureg.deg
+        )
+
+    # Rounding
+
+    # @helpers.requires_array_function_protocol()
+    def test_fix(self):
+        helpers.assert_quantity_equal(pnp.fix(3.13 * self.ureg.m), 3.0 * self.ureg.m)
+        helpers.assert_quantity_equal(pnp.fix(3.0 * self.ureg.m), 3.0 * self.ureg.m)
+        helpers.assert_quantity_equal(
+            pnp.fix([2.1, 2.9, -2.1, -2.9] * self.ureg.m),
+            [2.0, 2.0, -2.0, -2.0] * self.ureg.m,
+        )
+
+    # Sums, products, differences
+
+    # @helpers.requires_array_function_protocol()
+    def test_prod(self):
+        axis = 0
+        where = [[True, False], [True, True]]
+
+        helpers.assert_quantity_equal(self.q.prod(), 24 * self.ureg.m**4)
+        helpers.assert_quantity_equal(self.q.prod(axis=axis), [3, 8] * self.ureg.m**2)
+        helpers.assert_quantity_equal(self.q.prod(where=where), 12 * self.ureg.m**3)
+
+    # @helpers.requires_array_function_protocol()
+    def test_prod_numpy_func(self):
+        axis = 0
+        where = [[True, False], [True, True]]
+
+        helpers.assert_quantity_equal(pnp.prod(self.q), 24 * self.ureg.m**4)
+        helpers.assert_quantity_equal(
+            pnp.prod(self.q, axis=axis), [3, 8] * self.ureg.m**2
+        )
+        helpers.assert_quantity_equal(pnp.prod(self.q, where=where), 12 * self.ureg.m**3)
+
+        with pytest.raises(DimensionalityError):
+            pnp.prod(self.q, axis=axis, where=where)
+        helpers.assert_quantity_equal(
+            pnp.prod(self.q, axis=axis, where=[[True, False], [False, True]]),
+            [1, 4] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.prod(self.q, axis=axis, where=[True, False]), [3, 1] * self.ureg.m**2
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanprod_numpy_func(self):
+        helpers.assert_quantity_equal(pnp.nanprod(self.q_nan), 6 * self.ureg.m**3)
+        helpers.assert_quantity_equal(
+            pnp.nanprod(self.q_nan, axis=0), [3, 2] * self.ureg.m**2
+        )
+        helpers.assert_quantity_equal(
+            pnp.nanprod(self.q_nan, axis=1), [2, 3] * self.ureg.m**2
+        )
+
+    def test_sum(self):
+        assert self.q.sum() == 10 * self.ureg.m
+        helpers.assert_quantity_equal(self.q.sum(0), [4, 6] * self.ureg.m)
+        helpers.assert_quantity_equal(self.q.sum(1), [3, 7] * self.ureg.m)
+
+    # @helpers.requires_array_function_protocol()
+    def test_sum_numpy_func(self):
+        helpers.assert_quantity_equal(pnp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
+        with pytest.raises(OffsetUnitCalculusError):
+            pnp.sum(self.q_temperature)
+
+    # @helpers.requires_array_function_protocol()
+    def test_nansum_numpy_func(self):
+        helpers.assert_quantity_equal(
+            pnp.nansum(self.q_nan, axis=0), [4, 2] * self.ureg.m
+        )
+
+    def test_cumprod(self):
+        with pytest.raises(DimensionalityError):
+            self.q.cumprod()
+        helpers.assert_quantity_equal((self.q / self.ureg.m).cumprod(), [1, 2, 6, 24])
+
+    # @helpers.requires_array_function_protocol()
+    def test_cumprod_numpy_func(self):
+        with pytest.raises(DimensionalityError):
+            pnp.cumprod(self.q)
+        helpers.assert_quantity_equal(pnp.cumprod(self.q / self.ureg.m), [1, 2, 6, 24])
+        helpers.assert_quantity_equal(
+            pnp.cumprod(self.q / self.ureg.m, axis=1), [[1, 2], [3, 12]]
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_nancumprod_numpy_func(self):
+        with pytest.raises(DimensionalityError):
+            pnp.nancumprod(self.q_nan)
+        helpers.assert_quantity_equal(
+            pnp.nancumprod(self.q_nan / self.ureg.m), [1, 2, 6, 6]
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_diff(self):
+        helpers.assert_quantity_equal(pnp.diff(self.q, 1), [[1], [1]] * self.ureg.m)
+        helpers.assert_quantity_equal(
+            pnp.diff(self.q_temperature, 1), [[1], [1]] * self.ureg.delta_degC
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_ediff1d(self):
+        helpers.assert_quantity_equal(pnp.ediff1d(self.q), [1, 1, 1] * self.ureg.m)
+        helpers.assert_quantity_equal(
+            pnp.ediff1d(self.q_temperature), [1, 1, 1] * self.ureg.delta_degC
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_gradient(self):
+        grad = pnp.gradient([[1, 1], [3, 4]] * self.ureg.m, 1 * self.ureg.J)
+        helpers.assert_quantity_equal(
+            grad[0], [[2.0, 3.0], [2.0, 3.0]] * self.ureg.m / self.ureg.J
+        )
+        helpers.assert_quantity_equal(
+            grad[1], [[0.0, 0.0], [1.0, 1.0]] * self.ureg.m / self.ureg.J
+        )
+
+        grad = pnp.gradient(self.Q_([[1, 1], [3, 4]], self.ureg.degC), 1 * self.ureg.J)
+        helpers.assert_quantity_equal(
+            grad[0], [[2.0, 3.0], [2.0, 3.0]] * self.ureg.delta_degC / self.ureg.J
+        )
+        helpers.assert_quantity_equal(
+            grad[1], [[0.0, 0.0], [1.0, 1.0]] * self.ureg.delta_degC / self.ureg.J
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_cross(self):
+        a = [[3, -3, 1]] * self.ureg.kPa
+        b = [[4, 9, 2]] * self.ureg.m**2
+        helpers.assert_quantity_equal(
+            pnp.cross(a, b), [[-15, -2, 39]] * self.ureg.kPa * self.ureg.m**2
+        )
+
+    # NP2: Remove this when we only support np>=2.0
+    # @helpers.requires_array_function_protocol()
+    def test_trapz(self):
+        helpers.assert_quantity_equal(
+            pnp.trapz([1.0, 2.0, 3.0, 4.0] * self.ureg.J, dx=1 * self.ureg.m),
+            7.5 * self.ureg.J * self.ureg.m,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    # NP2: Remove this when we only support np>=2.0
+    # trapezoid added in numpy 2.0
+    # @helpers.requires_numpy_at_least("2.0")
+    def test_trapezoid(self):
+        helpers.assert_quantity_equal(
+            pnp.trapezoid([1.0, 2.0, 3.0, 4.0] * self.ureg.J, dx=1 * self.ureg.m),
+            7.5 * self.ureg.J * self.ureg.m,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_dot(self):
+        helpers.assert_quantity_equal(
+            self.q.ravel().dot(np.array([1, 0, 0, 1])), 5 * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_dot_numpy_func(self):
+        helpers.assert_quantity_equal(
+            pnp.dot(self.q.ravel(), [0, 0, 1, 0] * self.ureg.dimensionless),
+            3 * self.ureg.m,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_einsum(self):
+        a = pnp.arange(25).reshape(5, 5) * self.ureg.m
+        b = pnp.arange(5) * self.ureg.m
+        helpers.assert_quantity_equal(pnp.einsum("ii", a), 60 * self.ureg.m)
+        helpers.assert_quantity_equal(
+            pnp.einsum("ii->i", a), np.array([0, 6, 12, 18, 24]) * self.ureg.m
+        )
+        helpers.assert_quantity_equal(pnp.einsum("i,i", b, b), 30 * self.ureg.m**2)
+        helpers.assert_quantity_equal(
+            pnp.einsum("ij,j", a, b),
+            np.array([30, 80, 130, 180, 230]) * self.ureg.m**2,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_solve(self):
+        A = self.q
+        b = [[3], [7]] * self.ureg.s
+        x = pnp.linalg.solve(A, b)
+
+        helpers.assert_quantity_almost_equal(x, self.Q_([[1], [1]], "s / m"))
+
+        helpers.assert_quantity_almost_equal(pnp.dot(A, x), b)
+
+    # Arithmetic operations
+    def test_addition_with_scalar(self):
+        a = np.array([0, 1, 2])
+        b = 10.0 * self.ureg("gram/kilogram")
+        helpers.assert_quantity_almost_equal(
+            a + b, self.Q_([0.01, 1.01, 2.01], self.ureg.dimensionless)
+        )
+        helpers.assert_quantity_almost_equal(
+            b + a, self.Q_([0.01, 1.01, 2.01], self.ureg.dimensionless)
+        )
+
+    def test_addition_with_incompatible_scalar(self):
+        a = np.array([0, 1, 2])
+        b = 1.0 * self.ureg.m
+        with pytest.raises(DimensionalityError):
+            op.add(a, b)
+        with pytest.raises(DimensionalityError):
+            op.add(b, a)
+
+    def test_power(self):
+        arr = np.array(range(3), dtype=float)
+        q = self.Q_(arr, "meter")
+
+        for op_ in (op.pow, op.ipow, pnp.power):
+            q_cp = copy.copy(q)
+            with pytest.raises(DimensionalityError):
+                op_(2.0, q_cp)
+            arr_cp = copy.copy(arr)
+            arr_cp = copy.copy(arr)
+            q_cp = copy.copy(q)
+            with pytest.raises(DimensionalityError):
+                op_(q_cp, arr_cp)
+            q_cp = copy.copy(q)
+            q2_cp = copy.copy(q)
+            with pytest.raises(DimensionalityError):
+                op_(q_cp, q2_cp)
+
+        helpers.assert_quantity_equal(
+            pnp.power(self.q, self.Q_(2)), self.Q_([[1, 4], [9, 16]], "m**2")
+        )
+        helpers.assert_quantity_equal(
+            self.q ** self.Q_(2), self.Q_([[1, 4], [9, 16]], "m**2")
+        )
+        self.assertNDArrayEqual(arr ** self.Q_(2), np.array([0, 1, 4]))
+
+    def test_sqrt(self):
+        q = self.Q_(100, "m**2")
+        helpers.assert_quantity_equal(pnp.sqrt(q), self.Q_(10, "m"))
+
+    def test_cbrt(self):
+        q = self.Q_(1000, "m**3")
+        helpers.assert_quantity_equal(pnp.cbrt(q), self.Q_(10, "m"))
+
+    @pytest.mark.xfail
+    # @helpers.requires_numpy
+    def test_exponentiation_array_exp_2(self):
+        arr = np.array(range(3), dtype=float)
+        # q = self.Q_(copy.copy(arr), None)
+        q = self.Q_(copy.copy(arr), "meter")
+        arr_cp = copy.copy(arr)
+        q_cp = copy.copy(q)
+        # this fails as expected since numpy 1.8.0 but...
+        with pytest.raises(DimensionalityError):
+            op.pow(arr_cp, q_cp)
+        # ..not for op.ipow !
+        # q_cp is treated as if it is an array. The units are ignored.
+        # Quantity.__ipow__ is never called
+        arr_cp = copy.copy(arr)
+        q_cp = copy.copy(q)
+        with pytest.raises(DimensionalityError):
+            op.ipow(arr_cp, q_cp)
+
+
+class TestNumpyUnclassified(TestNumpyMethods):
+    def test_tolist(self):
+        with pytest.raises(AttributeError):
+            (5 * self.ureg.m).tolist()
+
+        assert self.q.tolist() == [
+            [1 * self.ureg.m, 2 * self.ureg.m],
+            [3 * self.ureg.m, 4 * self.ureg.m],
+        ]
+
+    def test_fill(self):
+        tmp = self.q
+        tmp.fill(6 * self.ureg.ft)
+        helpers.assert_quantity_equal(tmp, [[6, 6], [6, 6]] * self.ureg.ft)
+        tmp.fill(5 * self.ureg.m)
+        helpers.assert_quantity_equal(tmp, [[5, 5], [5, 5]] * self.ureg.m)
+
+    def test_take(self):
+        helpers.assert_quantity_equal(self.q.take([0, 1, 2, 3]), self.q.flatten())
+
+    def test_put(self):
+        q = [1.0, 2.0, 3.0, 4.0] * self.ureg.m
+        q.put([0, 2], [10.0, 20.0] * self.ureg.m)
+        helpers.assert_quantity_equal(q, [10.0, 2.0, 20.0, 4.0] * self.ureg.m)
+
+        q = [1.0, 2.0, 3.0, 4.0] * self.ureg.m
+        q.put([0, 2], [1.0, 2.0] * self.ureg.mm)
+        helpers.assert_quantity_equal(q, [0.001, 2.0, 0.002, 4.0] * self.ureg.m)
+
+        q = [1.0, 2.0, 3.0, 4.0] * self.ureg.m / self.ureg.mm
+        q.put([0, 2], [1.0, 2.0])
+        helpers.assert_quantity_equal(
+            q, [0.001, 2.0, 0.002, 4.0] * self.ureg.m / self.ureg.mm
+        )
+
+        q = [1.0, 2.0, 3.0, 4.0] * self.ureg.m
+        with pytest.raises(DimensionalityError):
+            q.put([0, 2], [4.0, 6.0] * self.ureg.J)
+        with pytest.raises(DimensionalityError):
+            q.put([0, 2], [4.0, 6.0])
+
+    def test_repeat(self):
+        helpers.assert_quantity_equal(
+            self.q.repeat(2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
+        )
+
+    def test_sort(self):
+        q = [4, 5, 2, 3, 1, 6] * self.ureg.m
+        q.sort()
+        helpers.assert_quantity_equal(q, [1, 2, 3, 4, 5, 6] * self.ureg.m)
+
+    # @helpers.requires_array_function_protocol()
+    def test_sort_numpy_func(self):
+        q = [4, 5, 2, 3, 1, 6] * self.ureg.m
+        helpers.assert_quantity_equal(pnp.sort(q), [1, 2, 3, 4, 5, 6] * self.ureg.m)
+
+    def test_argsort(self):
+        q = [1, 4, 5, 6, 2, 9] * self.ureg.MeV
+        self.assertNDArrayEqual(q.argsort(), [0, 4, 1, 2, 3, 5])
+
+    # @helpers.requires_array_function_protocol()
+    def test_argsort_numpy_func(self):
+        self.assertNDArrayEqual(pnp.argsort(self.q, axis=0), np.array([[0, 0], [1, 1]]))
+
+    def test_diagonal(self):
+        q = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] * self.ureg.m
+        helpers.assert_quantity_equal(q.diagonal(offset=1), [2, 3] * self.ureg.m)
+
+    # @helpers.requires_array_function_protocol()
+    def test_diagonal_numpy_func(self):
+        q = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] * self.ureg.m
+        helpers.assert_quantity_equal(pnp.diagonal(q, offset=-1), [1, 2] * self.ureg.m)
+
+    def test_compress(self):
+        helpers.assert_quantity_equal(
+            self.q.compress([False, True], axis=0), [[3, 4]] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            self.q.compress([False, True], axis=1), [[2], [4]] * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_compress_nep18(self):
+        helpers.assert_quantity_equal(
+            pnp.compress([False, True], self.q, axis=1), [[2], [4]] * self.ureg.m
+        )
+
+    def test_searchsorted(self):
+        q = self.q.flatten()
+        self.assertNDArrayEqual(q.searchsorted([1.5, 2.5] * self.ureg.m), [1, 2])
+        q = self.q.flatten()
+        with pytest.raises(DimensionalityError):
+            q.searchsorted([1.5, 2.5])
+
+    # @helpers.requires_array_function_protocol()
+    def test_searchsorted_numpy_func(self):
+        """Test searchsorted as numpy function."""
+        q = self.q.flatten()
+        self.assertNDArrayEqual(pnp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
+
+    def test_nonzero(self):
+        q = [1, 0, 5, 6, 0, 9] * self.ureg.m
+        self.assertNDArrayEqual(q.nonzero()[0], [0, 2, 3, 5])
+
+    # @helpers.requires_array_function_protocol()
+    def test_nonzero_numpy_func(self):
+        q = [1, 0, 5, 6, 0, 9] * self.ureg.m
+        self.assertNDArrayEqual(pnp.nonzero(q)[0], [0, 2, 3, 5])
+
+    # @helpers.requires_array_function_protocol()
+    def test_any_numpy_func(self):
+        q = [0, 1] * self.ureg.m
+        assert pnp.any(q)
+        with pytest.raises(ValueError):
+            pnp.any(self.q_temperature)
+
+    # @helpers.requires_array_function_protocol()
+    def test_all_numpy_func(self):
+        q = [0, 1] * self.ureg.m
+        assert not pnp.all(q)
+        with pytest.raises(ValueError):
+            pnp.all(self.q_temperature)
+
+    # @helpers.requires_array_function_protocol()
+    def test_count_nonzero_numpy_func(self):
+        q = [1, 0, 5, 6, 0, 9] * self.ureg.m
+        assert pnp.count_nonzero(q) == 4
+
+    def test_max(self):
+        assert self.q.max() == 4 * self.ureg.m
+
+    def test_max_numpy_func(self):
+        assert pnp.max(self.q) == 4 * self.ureg.m
+
+    # @helpers.requires_array_function_protocol()
+    def test_max_with_axis_arg(self):
+        helpers.assert_quantity_equal(pnp.max(self.q, axis=1), [2, 4] * self.ureg.m)
+
+    # @helpers.requires_array_function_protocol()
+    def test_max_with_initial_arg(self):
+        helpers.assert_quantity_equal(
+            pnp.max(self.q[..., None], axis=2, initial=3 * self.ureg.m),
+            [[3, 3], [3, 4]] * self.ureg.m,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanmax(self):
+        assert pnp.nanmax(self.q_nan) == 3 * self.ureg.m
+
+    def test_argmax(self):
+        assert self.q.argmax() == 3
+
+    # @helpers.requires_array_function_protocol()
+    def test_argmax_numpy_func(self):
+        self.assertNDArrayEqual(pnp.argmax(self.q, axis=0), np.array([1, 1]))
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanargmax_numpy_func(self):
+        self.assertNDArrayEqual(pnp.nanargmax(self.q_nan, axis=0), np.array([1, 0]))
+
+    def test_maximum(self):
+        helpers.assert_quantity_equal(
+            pnp.maximum(self.q, self.Q_([0, 5], "m")), self.Q_([[1, 5], [3, 5]], "m")
+        )
+
+    def test_min(self):
+        assert self.q.min() == 1 * self.ureg.m
+
+    # @helpers.requires_array_function_protocol()
+    def test_min_numpy_func(self):
+        assert pnp.min(self.q) == 1 * self.ureg.m
+
+    # @helpers.requires_array_function_protocol()
+    def test_min_with_axis_arg(self):
+        helpers.assert_quantity_equal(pnp.min(self.q, axis=1), [1, 3] * self.ureg.m)
+
+    # @helpers.requires_array_function_protocol()
+    def test_min_with_initial_arg(self):
+        helpers.assert_quantity_equal(
+            pnp.min(self.q[..., None], axis=2, initial=3 * self.ureg.m),
+            [[1, 2], [3, 3]] * self.ureg.m,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanmin(self):
+        assert pnp.nanmin(self.q_nan) == 1 * self.ureg.m
+
+    def test_argmin(self):
+        assert self.q.argmin() == 0
+
+    # @helpers.requires_array_function_protocol()
+    def test_argmin_numpy_func(self):
+        self.assertNDArrayEqual(pnp.argmin(self.q, axis=0), np.array([0, 0]))
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanargmin_numpy_func(self):
+        self.assertNDArrayEqual(pnp.nanargmin(self.q_nan, axis=0), np.array([0, 0]))
+
+    def test_minimum(self):
+        helpers.assert_quantity_equal(
+            pnp.minimum(self.q, self.Q_([0, 5], "m")), self.Q_([[0, 2], [0, 4]], "m")
+        )
+
+    # NP2: Can remove Q_(arr).ptp test when we only support numpy>=2
+    def test_ptp(self):
+        if not pnp.lib.NumpyVersion(pnp.__version__) >= "2.0.0b1":
+            assert self.q.ptp() == 3 * self.ureg.m
+
+    # NP2: Keep this test for numpy>=2, it's only arr.ptp() that is deprecated
+    # @helpers.requires_array_function_protocol()
+    def test_ptp_numpy_func(self):
+        helpers.assert_quantity_equal(pnp.ptp(self.q, axis=0), [2, 2] * self.ureg.m)
+
+    def test_clip(self):
+        helpers.assert_quantity_equal(
+            self.q.clip(max=2 * self.ureg.m), [[1, 2], [2, 2]] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            self.q.clip(min=3 * self.ureg.m), [[3, 3], [3, 4]] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            self.q.clip(min=2 * self.ureg.m, max=3 * self.ureg.m),
+            [[2, 2], [3, 3]] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            self.q.clip(3 * self.ureg.m, None), [[3, 3], [3, 4]] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            self.q.clip(3 * self.ureg.m), [[3, 3], [3, 4]] * self.ureg.m
+        )
+        with pytest.raises(DimensionalityError):
+            self.q.clip(self.ureg.J)
+        with pytest.raises(DimensionalityError):
+            self.q.clip(1)
+
+    # @helpers.requires_array_function_protocol()
+    def test_clip_numpy_func(self):
+        helpers.assert_quantity_equal(
+            pnp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
+        )
+
+    def test_round(self):
+        q = [1, 1.33, 5.67, 22] * self.ureg.m
+        helpers.assert_quantity_equal(q.round(0), [1, 1, 6, 22] * self.ureg.m)
+        helpers.assert_quantity_equal(q.round(-1), [0, 0, 10, 20] * self.ureg.m)
+        helpers.assert_quantity_equal(q.round(1), [1, 1.3, 5.7, 22] * self.ureg.m)
+
+    # @helpers.requires_array_function_protocol()
+    def test_round_numpy_func(self):
+        helpers.assert_quantity_equal(
+            pnp.around(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            pnp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
+        )
+
+    def test_trace(self):
+        assert self.q.trace() == (1 + 4) * self.ureg.m
+
+    def test_cumsum(self):
+        helpers.assert_quantity_equal(self.q.cumsum(), [1, 3, 6, 10] * self.ureg.m)
+
+    # @helpers.requires_array_function_protocol()
+    def test_cumsum_numpy_func(self):
+        helpers.assert_quantity_equal(
+            pnp.cumsum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_nancumsum_numpy_func(self):
+        helpers.assert_quantity_equal(
+            pnp.nancumsum(self.q_nan, axis=0), [[1, 2], [4, 2]] * self.ureg.m
+        )
+
+    def test_mean(self):
+        assert self.q.mean() == 2.5 * self.ureg.m
+
+    # @helpers.requires_array_function_protocol()
+    def test_mean_numpy_func(self):
+        assert pnp.mean(self.q) == 2.5 * self.ureg.m
+        assert pnp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanmean_numpy_func(self):
+        assert pnp.nanmean(self.q_nan) == 2 * self.ureg.m
+
+    # @helpers.requires_array_function_protocol()
+    def test_average_numpy_func(self):
+        helpers.assert_quantity_almost_equal(
+            pnp.average(self.q, axis=0, weights=[1, 2]),
+            [2.33333, 3.33333] * self.ureg.m,
+            rtol=1e-5,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_median_numpy_func(self):
+        assert pnp.median(self.q) == 2.5 * self.ureg.m
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanmedian_numpy_func(self):
+        assert pnp.nanmedian(self.q_nan) == 2 * self.ureg.m
+
+    def test_var(self):
+        assert self.q.var() == 1.25 * self.ureg.m**2
+
+    # @helpers.requires_array_function_protocol()
+    def test_var_numpy_func(self):
+        assert pnp.var(self.q) == 1.25 * self.ureg.m**2
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanvar_numpy_func(self):
+        helpers.assert_quantity_almost_equal(
+            pnp.nanvar(self.q_nan), 0.66667 * self.ureg.m**2, rtol=1e-5
+        )
+
+    def test_std(self):
+        helpers.assert_quantity_almost_equal(
+            self.q.std(), 1.11803 * self.ureg.m, rtol=1e-5
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_std_numpy_func(self):
+        helpers.assert_quantity_almost_equal(
+            pnp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
+        )
+        with pytest.raises(OffsetUnitCalculusError):
+            pnp.std(self.q_temperature)
+
+    def test_cumprod(self):
+        with pytest.raises(DimensionalityError):
+            self.q.cumprod()
+        helpers.assert_quantity_equal((self.q / self.ureg.m).cumprod(), [1, 2, 6, 24])
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanstd_numpy_func(self):
+        helpers.assert_quantity_almost_equal(
+            pnp.nanstd(self.q_nan), 0.81650 * self.ureg.m, rtol=1e-5
+        )
+
+    def test_conj(self):
+        helpers.assert_quantity_equal((self.q * (1 + 1j)).conj(), self.q * (1 - 1j))
+        helpers.assert_quantity_equal(
+            (self.q * (1 + 1j)).conjugate(), self.q * (1 - 1j)
+        )
+
+    def test_getitem(self):
+        with pytest.raises(IndexError):
+            self.q.__getitem__((0, 10))
+        helpers.assert_quantity_equal(self.q[0], [1, 2] * self.ureg.m)
+        assert self.q[1, 1] == 4 * self.ureg.m
+
+    def test_setitem(self):
+        with pytest.raises(TypeError):
+            self.q[0, 0] = 1
+        with pytest.raises(DimensionalityError):
+            self.q[0, 0] = 1 * self.ureg.J
+        with pytest.raises(DimensionalityError):
+            self.q[0] = 1
+        with pytest.raises(DimensionalityError):
+            self.q[0] = pnp.ndarray([1, 2])
+        with pytest.raises(DimensionalityError):
+            self.q[0] = 1 * self.ureg.J
+
+        q = self.q.copy()
+        q[0] = 1 * self.ureg.m
+        helpers.assert_quantity_equal(q, [[1, 1], [3, 4]] * self.ureg.m)
+
+        q = self.q.copy()
+        q[...] = 1 * self.ureg.m
+        helpers.assert_quantity_equal(q, [[1, 1], [1, 1]] * self.ureg.m)
+
+        q = self.q.copy()
+        q[:] = 1 * self.ureg.m
+        helpers.assert_quantity_equal(q, [[1, 1], [1, 1]] * self.ureg.m)
+
+        # check and see that dimensionless numbers work correctly
+        q = [0, 1, 2, 3] * self.ureg.dimensionless
+        q[0] = 1
+        helpers.assert_quantity_equal(q, pnp.asarray([1, 1, 2, 3]))
+        q[0] = self.ureg.m / self.ureg.mm
+        helpers.assert_quantity_equal(q, pnp.asarray([1000, 1, 2, 3]))
+
+        q = [0.0, 1.0, 2.0, 3.0] * self.ureg.m / self.ureg.mm
+        q[0] = 1.0
+        helpers.assert_quantity_equal(q, [0.001, 1, 2, 3] * self.ureg.m / self.ureg.mm)
+
+        # Check that this properly masks the first item without warning
+        q = self.ureg.Quantity(
+            pnp.ma.array([0.0, 1.0, 2.0, 3.0], mask=[False, True, False, False]), "m"
+        )
+        with warnings.catch_warnings(record=True) as w:
+            q[0] = pnp.ma.masked
+            # Check for no warnings
+            assert not w
+            assert q.mask[0]
+
+    def test_setitem_mixed_masked(self):
+        masked = pnp.ma.array(
+            [
+                1,
+                2,
+            ],
+            mask=[True, False],
+        )
+        q = self.Q_(pnp.ones(shape=(2,)), "m")
+        with pytest.raises(DimensionalityError):
+            q[:] = masked
+
+        masked_q = self.Q_(masked, "mm")
+        q[:] = masked_q
+        helpers.assert_quantity_equal(q, [1.0, 0.002] * self.ureg.m)
+
+    def test_iterator(self):
+        for q, v in zip(self.q.flatten(), [1, 2, 3, 4]):
+            assert q == v * self.ureg.m
+
+    def test_iterable(self):
+        assert pnp.iterable(self.q)
+        assert not pnp.iterable(1 * self.ureg.m)
+
+    def test_reversible_op(self):
+        """ """
+        x = self.q.magnitude
+        u = self.Q_(pnp.ones(x.shape))
+        helpers.assert_quantity_equal(x / self.q, u * x / self.q)
+        helpers.assert_quantity_equal(x * self.q, u * x * self.q)
+        helpers.assert_quantity_equal(x + u, u + x)
+        helpers.assert_quantity_equal(x - u, -(u - x))
+
+    def test_pickle(self, subtests):
+        for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
+            with subtests.test(protocol):
+                q1 = [10, 20] * self.ureg.m
+                q2 = pickle.loads(pickle.dumps(q1, protocol))
+                self.assertNDArrayEqual(q1.magnitude, q2.magnitude)
+                assert q1.units == q2.units
+
+    def test_equal(self):
+        x = self.q.magnitude
+        u = self.Q_(pnp.ones(x.shape))
+        true = pnp.ones_like(x, dtype=pnp.bool_)
+        false = pnp.zeros_like(x, dtype=pnp.bool_)
+
+        helpers.assert_quantity_equal(u, u)
+        helpers.assert_quantity_equal(u == u, u.magnitude == u.magnitude)
+        helpers.assert_quantity_equal(u == 1, u.magnitude == 1)
+
+        v = self.Q_(pnp.zeros(x.shape), "m")
+        w = self.Q_(pnp.ones(x.shape), "m")
+        self.assertNDArrayEqual(v == 1, false)
+        self.assertNDArrayEqual(
+            self.Q_(pnp.zeros_like(x), "m") == self.Q_(pnp.zeros_like(x), "s"),
+            false,
+        )
+        self.assertNDArrayEqual(v == v, true)
+        self.assertNDArrayEqual(v == w, false)
+        self.assertNDArrayEqual(v == w.to("mm"), false)
+        self.assertNDArrayEqual(u == v, false)
+
+    def test_shape(self):
+        u = self.Q_(pnp.arange(12))
+        u.shape = 4, 3
+        assert u.magnitude.shape == (4, 3)
+
+    def test_dtype(self):
+        u = self.Q_(pnp.arange(12, dtype="uint32"))
+
+        assert u.dtype == "uint32"
+
+    # @helpers.requires_array_function_protocol()
+    def test_shape_numpy_func(self):
+        assert pnp.shape(self.q) == (2, 2)
+
+    # @helpers.requires_array_function_protocol()
+    def test_len_numpy_func(self):
+        assert len(self.q) == 2
+
+    # @helpers.requires_array_function_protocol()
+    def test_ndim_numpy_func(self):
+        assert pnp.ndim(self.q) == 2
+
+    # @helpers.requires_array_function_protocol()
+    def test_copy_numpy_func(self):
+        q_copy = pnp.copy(self.q)
+        helpers.assert_quantity_equal(self.q, q_copy)
+        assert self.q is not q_copy
+
+    # @helpers.requires_array_function_protocol()
+    def test_trim_zeros_numpy_func(self):
+        q = [0, 4, 3, 0, 2, 2, 0, 0, 0] * self.ureg.m
+        helpers.assert_quantity_equal(pnp.trim_zeros(q), [4, 3, 0, 2, 2] * self.ureg.m)
+
+    # @helpers.requires_array_function_protocol()
+    def test_result_type_numpy_func(self):
+        assert pnp.result_type(self.q) == pnp.dtype("int")
+
+    # @helpers.requires_array_function_protocol()
+    def test_nan_to_num_numpy_func(self):
+        helpers.assert_quantity_equal(
+            pnp.nan_to_num(self.q_nan, nan=-999 * self.ureg.mm),
+            [[1, 2], [3, -0.999]] * self.ureg.m,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_meshgrid_numpy_func(self):
+        x = [1, 2] * self.ureg.m
+        y = [0, 50, 100] * self.ureg.mm
+        xx, yy = pnp.meshgrid(x, y)
+        helpers.assert_quantity_equal(xx, [[1, 2], [1, 2], [1, 2]] * self.ureg.m)
+        helpers.assert_quantity_equal(yy, [[0, 0], [50, 50], [100, 100]] * self.ureg.mm)
+
+    # @helpers.requires_array_function_protocol()
+    def test_isclose_numpy_func(self):
+        q2 = [[1000.05, 2000], [3000.00007, 4001]] * self.ureg.mm
+        self.assertNDArrayEqual(
+            pnp.isclose(self.q, q2), np.array([[False, True], [True, False]])
+        )
+        self.assertNDArrayEqual(
+            pnp.isclose(self.q, q2, atol=1e-5 * self.ureg.mm, rtol=1e-7),
+            np.array([[False, True], [True, False]]),
+        )
+        self.assertNDArrayEqual(
+            pnp.isclose(self.q, q2, atol=1e-5, rtol=1e-7),
+            np.array([[False, True], [True, False]]),
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_interp_numpy_func(self):
+        x = [1, 4] * self.ureg.m
+        xp = pnp.linspace(0, 3, 5) * self.ureg.m
+        fp = self.Q_([0, 5, 10, 15, 20], self.ureg.degC)
+        helpers.assert_quantity_almost_equal(
+            pnp.interp(x, xp, fp), self.Q_([6.66667, 20.0], self.ureg.degC), rtol=1e-5
+        )
+
+        x_ = np.array([1, 4])
+        xp_ = pnp.linspace(0, 3, 5)
+        fp_ = [0, 5, 10, 15, 20]
+
+        helpers.assert_quantity_almost_equal(
+            pnp.interp(x_, xp_, fp), self.Q_([6.6667, 20.0], self.ureg.degC), rtol=1e-5
+        )
+        helpers.assert_quantity_almost_equal(
+            pnp.interp(x, xp, fp_), [6.6667, 20.0], rtol=1e-5
+        )
+
+    def test_comparisons(self):
+        self.assertNDArrayEqual(
+            self.q > 2 * self.ureg.m, np.array([[False, False], [True, True]])
+        )
+        self.assertNDArrayEqual(
+            self.q < 2 * self.ureg.m, np.array([[True, False], [False, False]])
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_where(self):
+        helpers.assert_quantity_equal(
+            pnp.where(self.q >= 2 * self.ureg.m, self.q, 20 * self.ureg.m),
+            [[20, 2], [3, 4]] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.where(self.q >= 2 * self.ureg.m, self.q, 0),
+            [[0, 2], [3, 4]] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.where(self.q >= 2 * self.ureg.m, self.q, pnp.nan),
+            [[pnp.nan, 2], [3, 4]] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.where(self.q >= 3 * self.ureg.m, 0, self.q),
+            [[1, 2], [0, 0]] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.where(self.q >= 3 * self.ureg.m, pnp.nan, self.q),
+            [[1, 2], [pnp.nan, pnp.nan]] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.where(self.q >= 2 * self.ureg.m, self.q, np.array(pnp.nan)),
+            [[pnp.nan, 2], [3, 4]] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.where(self.q >= 3 * self.ureg.m, np.array(pnp.nan), self.q),
+            [[1, 2], [pnp.nan, pnp.nan]] * self.ureg.m,
+        )
+        with pytest.raises(DimensionalityError):
+            pnp.where(
+                self.q < 2 * self.ureg.m,
+                self.q,
+                0 * self.ureg.J,
+            )
+
+        helpers.assert_quantity_equal(
+            pnp.where([-1, 0, 1] * self.ureg.m, [1, 2, 1] * self.ureg.s, pnp.nan),
+            [1, pnp.nan, 1] * self.ureg.s,
+        )
+        with pytest.raises(
+            ValueError,
+            match=".*Boolean value of Quantity with offset unit is ambiguous",
+        ):
+            pnp.where(
+                self.ureg.Quantity([-1, 0, 1], "degC"), [1, 2, 1] * self.ureg.s, pnp.nan
+            )
+
+    # @helpers.requires_array_function_protocol()
+    def test_fabs(self):
+        helpers.assert_quantity_equal(
+            pnp.fabs(self.q - 2 * self.ureg.m), self.Q_([[1, 0], [1, 2]], "m")
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_isin(self):
+        self.assertNDArrayEqual(
+            pnp.isin(self.q, self.Q_([0, 2, 4], "m")),
+            np.array([[False, True], [False, True]]),
+        )
+        self.assertNDArrayEqual(
+            pnp.isin(self.q, self.Q_([0, 2, 4], "J")),
+            np.array([[False, False], [False, False]]),
+        )
+        self.assertNDArrayEqual(
+            pnp.isin(self.q, [self.Q_(2, "m"), self.Q_(4, "J")]),
+            np.array([[False, True], [False, False]]),
+        )
+        self.assertNDArrayEqual(
+            pnp.isin(self.q, self.q.m), np.array([[False, False], [False, False]])
+        )
+        self.assertNDArrayEqual(
+            pnp.isin(self.q / self.ureg.cm, [1, 3]),
+            np.array([[True, False], [True, False]]),
+        )
+        with pytest.raises(ValueError):
+            pnp.isin(self.q.m, self.q)
+
+    # @helpers.requires_array_function_protocol()
+    def test_percentile(self):
+        helpers.assert_quantity_equal(pnp.percentile(self.q, 25), self.Q_(1.75, "m"))
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanpercentile(self):
+        helpers.assert_quantity_equal(
+            pnp.nanpercentile(self.q_nan, 25), self.Q_(1.5, "m")
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_quantile(self):
+        helpers.assert_quantity_equal(pnp.quantile(self.q, 0.25), self.Q_(1.75, "m"))
+
+    # @helpers.requires_array_function_protocol()
+    def test_nanquantile(self):
+        helpers.assert_quantity_equal(
+            pnp.nanquantile(self.q_nan, 0.25), self.Q_(1.5, "m")
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_copyto(self):
+        a = self.q.m
+        q = copy.copy(self.q)
+        pnp.copyto(q, 2 * q, where=[True, False])
+        helpers.assert_quantity_equal(q, self.Q_([[2, 2], [6, 4]], "m"))
+        pnp.copyto(q, 0, where=[[False, False], [True, False]])
+        helpers.assert_quantity_equal(q, self.Q_([[2, 2], [0, 4]], "m"))
+        pnp.copyto(a, q)
+        self.assertNDArrayEqual(a, np.array([[2, 2], [0, 4]]))
+
+    # @helpers.requires_array_function_protocol()
+    def test_tile(self):
+        helpers.assert_quantity_equal(
+            pnp.tile(self.q, 2), np.array([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m
+        )
+
+    # @helpers.requires_numpy_at_least("1.20")
+    # @helpers.requires_array_function_protocol()
+    def test_sliding_window_view(self):
+        q = self.Q_([[1, 2, 2, 1], [2, 1, 1, 2], [1, 2, 2, 1]], "m")
+        actual = pnp.lib.stride_tricks.sliding_window_view(q, window_shape=(3, 3))
+        expected = self.Q_(
+            [[[[1, 2, 2], [2, 1, 1], [1, 2, 2]], [[2, 2, 1], [1, 1, 2], [2, 2, 1]]]],
+            "m",
+        )
+        helpers.assert_quantity_equal(actual, expected)
+
+    # @helpers.requires_array_function_protocol()
+    def test_rot90(self):
+        helpers.assert_quantity_equal(
+            pnp.rot90(self.q), np.array([[2, 4], [1, 3]]) * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_insert(self):
+        helpers.assert_quantity_equal(
+            pnp.insert(self.q, 1, 0 * self.ureg.m, axis=1),
+            np.array([[1, 0, 2], [3, 0, 4]]) * self.ureg.m,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_delete(self):
+        q = self.Q_(np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]), "m")
+        helpers.assert_quantity_equal(
+            pnp.delete(q, 1, axis=0),
+            np.array([[1, 2, 3, 4], [9, 10, 11, 12]]) * self.ureg.m,
+        )
+
+        helpers.assert_quantity_equal(
+            pnp.delete(q, pnp.s_[::2], 1),
+            np.array([[2, 4], [6, 8], [10, 12]]) * self.ureg.m,
+        )
+
+        helpers.assert_quantity_equal(
+            pnp.delete(q, [1, 3, 5], None),
+            np.array([1, 3, 5, 7, 8, 9, 10, 11, 12]) * self.ureg.m,
+        )
+
+    def test_ndarray_downcast(self):
+        with pytest.warns(UnitStrippedWarning):
+            pnp.asarray(self.q)
+
+    def test_ndarray_downcast_with_dtype(self):
+        with pytest.warns(UnitStrippedWarning):
+            qarr = pnp.asarray(self.q, dtype=pnp.float64)
+            assert qarr.dtype == pnp.float64
+
+    def test_array_protocol_unavailable(self):
+        for attr in ("__array_struct__", "__array_interface__"):
+            with pytest.raises(AttributeError):
+                getattr(self.q, attr)
+
+    # @helpers.requires_array_function_protocol()
+    def test_resize(self):
+        helpers.assert_quantity_equal(
+            pnp.resize(self.q, (2, 4)), [[1, 2, 3, 4], [1, 2, 3, 4]] * self.ureg.m
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_pad(self):
+        # Tests reproduced with modification from NumPy documentation
+        a = [1, 2, 3, 4, 5] * self.ureg.m
+        b = self.Q_([4.0, 6.0, 8.0, 9.0, -3.0], "degC")
+
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2, 3), "constant"), [0, 0, 1, 2, 3, 4, 5, 0, 0, 0] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2, 3), "constant", constant_values=(0, 600 * self.ureg.cm)),
+            [0, 0, 1, 2, 3, 4, 5, 6, 6, 6] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(
+                b, (2, 1), "constant", constant_values=(pnp.nan, self.Q_(10, "degC"))
+            ),
+            self.Q_([pnp.nan, pnp.nan, 4, 6, 8, 9, -3, 10], "degC"),
+        )
+        with pytest.raises(DimensionalityError):
+            pnp.pad(a, (2, 3), "constant", constant_values=4)
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2, 3), "edge"), [1, 1, 1, 2, 3, 4, 5, 5, 5, 5] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2, 3), "linear_ramp"),
+            [0, 0, 1, 2, 3, 4, 5, 3, 1, 0] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2, 3), "linear_ramp", end_values=(5, -4) * self.ureg.m),
+            [5, 3, 1, 2, 3, 4, 5, 2, -1, -4] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2,), "maximum"), [5, 5, 1, 2, 3, 4, 5, 5, 5] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2,), "mean"), [3, 3, 1, 2, 3, 4, 5, 3, 3] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2,), "median"), [3, 3, 1, 2, 3, 4, 5, 3, 3] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(self.q, ((3, 2), (2, 3)), "minimum"),
+            [
+                [1, 1, 1, 2, 1, 1, 1],
+                [1, 1, 1, 2, 1, 1, 1],
+                [1, 1, 1, 2, 1, 1, 1],
+                [1, 1, 1, 2, 1, 1, 1],
+                [3, 3, 3, 4, 3, 3, 3],
+                [1, 1, 1, 2, 1, 1, 1],
+                [1, 1, 1, 2, 1, 1, 1],
+            ]
+            * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2, 3), "reflect"), [3, 2, 1, 2, 3, 4, 5, 4, 3, 2] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2, 3), "reflect", reflect_type="odd"),
+            [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2, 3), "symmetric"), [2, 1, 1, 2, 3, 4, 5, 5, 4, 3] * self.ureg.m
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2, 3), "symmetric", reflect_type="odd"),
+            [0, 1, 1, 2, 3, 4, 5, 5, 6, 7] * self.ureg.m,
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(a, (2, 3), "wrap"), [4, 5, 1, 2, 3, 4, 5, 1, 2, 3] * self.ureg.m
+        )
+
+        def pad_with(vector, pad_width, iaxis, kwargs):
+            pad_value = kwargs.get("padder", 10)
+            vector[: pad_width[0]] = pad_value
+            vector[-pad_width[1] :] = pad_value
+
+        b = self.Q_(pnp.arange(6).reshape((2, 3)), "degC")
+        helpers.assert_quantity_equal(
+            pnp.pad(b, 2, pad_with),
+            self.Q_(
+                [
+                    [10, 10, 10, 10, 10, 10, 10],
+                    [10, 10, 10, 10, 10, 10, 10],
+                    [10, 10, 0, 1, 2, 10, 10],
+                    [10, 10, 3, 4, 5, 10, 10],
+                    [10, 10, 10, 10, 10, 10, 10],
+                    [10, 10, 10, 10, 10, 10, 10],
+                ],
+                "degC",
+            ),
+        )
+        helpers.assert_quantity_equal(
+            pnp.pad(b, 2, pad_with, padder=100),
+            self.Q_(
+                [
+                    [100, 100, 100, 100, 100, 100, 100],
+                    [100, 100, 100, 100, 100, 100, 100],
+                    [100, 100, 0, 1, 2, 100, 100],
+                    [100, 100, 3, 4, 5, 100, 100],
+                    [100, 100, 100, 100, 100, 100, 100],
+                    [100, 100, 100, 100, 100, 100, 100],
+                ],
+                "degC",
+            ),
+        )  # Note: Does not support Quantity pad_with vectorized callable use
+
+    # @helpers.requires_array_function_protocol()
+    def test_allclose(self):
+        assert pnp.allclose([1e10, 1e-8] * self.ureg.m, [1.00001e10, 1e-9] * self.ureg.m)
+        assert pnp.allclose(
+            [1e10, 1e-8] * self.ureg.m, [1.00001e13, 1e-6] * self.ureg.mm
+        )
+        assert not pnp.allclose(
+            [1e10, 1e-8] * self.ureg.m, [1.00001e10, 1e-9] * self.ureg.mm
+        )
+        assert pnp.allclose(
+            [1e10, 1e-8] * self.ureg.m,
+            [1.00001e10, 1e-9] * self.ureg.m,
+            atol=1e-8 * self.ureg.m,
+        )
+
+        assert not pnp.allclose([1.0, pnp.nan] * self.ureg.m, [1.0, pnp.nan] * self.ureg.m)
+
+        assert pnp.allclose(
+            [1.0, pnp.nan] * self.ureg.m, [1.0, pnp.nan] * self.ureg.m, equal_nan=True
+        )
+
+        assert pnp.allclose(
+            [1e10, 1e-8] * self.ureg.m, [1.00001e10, 1e-9] * self.ureg.m, atol=1e-8
+        )
+
+        with pytest.raises(DimensionalityError):
+            assert pnp.allclose(
+                [1e10, 1e-8] * self.ureg.m,
+                [1.00001e10, 1e-9] * self.ureg.m,
+                atol=1e-8 * self.ureg.s,
+            )
+
+    # @helpers.requires_array_function_protocol()
+    def test_intersect1d(self):
+        helpers.assert_quantity_equal(
+            pnp.intersect1d([1, 3, 4, 3] * self.ureg.m, [3, 1, 2, 1] * self.ureg.m),
+            [1, 3] * self.ureg.m,
+        )
+
+    # @helpers.requires_array_function_protocol()
+    def test_linalg_norm(self):
+        q = np.array([[3, 5, 8], [4, 12, 15]]) * self.ureg.m
+        expected = [5, 13, 17] * self.ureg.m
+        helpers.assert_quantity_equal(pnp.linalg.norm(q, axis=0), expected)
+
+
+@pytest.mark.skip
+class TestBitTwiddlingUfuncs(TestUFuncs):
+    """Universal functions (ufuncs) >  Bittwiddling functions
+
+    http://docs.scipy.org/doc/numpy/reference/ufuncs.html#bittwiddlingfunctions
+
+    bitwise_and(x1, x2[, out])         Compute the bitwise AND of two arrays elementwise.
+    bitwise_or(x1, x2[, out])  Compute the bitwise OR of two arrays elementwise.
+    bitwise_xor(x1, x2[, out])         Compute the bitwise XOR of two arrays elementwise.
+    invert(x[, out])   Compute bitwise inversion, or bitwise NOT, elementwise.
+    left_shift(x1, x2[, out])  Shift the bits of an integer to the left.
+    right_shift(x1, x2[, out])         Shift the bits of an integer to the right.
+
+    Parameters
+    ----------
+
+    Returns
+    -------
+
+    """
+
+    @property
+    def qless(self):
+        return pnp.asarray([1, 2, 3, 4], dtype=pnp.uint8) * self.ureg.dimensionless
+
+    @property
+    def qs(self):
+        return 8 * self.ureg.J
+
+    @property
+    def q1(self):
+        return pnp.asarray([1, 2, 3, 4], dtype=pnp.uint8) * self.ureg.J
+
+    @property
+    def q2(self):
+        return 2 * self.q1
+
+    @property
+    def qm(self):
+        return pnp.asarray([1, 2, 3, 4], dtype=pnp.uint8) * self.ureg.m
+
+    def test_bitwise_and(self):
+        self._test2(pnp.bitwise_and, self.q1, (self.q2, self.qs), (self.qm,), "same")
+
+    def test_bitwise_or(self):
+        self._test2(
+            pnp.bitwise_or, self.q1, (self.q1, self.q2, self.qs), (self.qm,), "same"
+        )
+
+    def test_bitwise_xor(self):
+        self._test2(
+            pnp.bitwise_xor, self.q1, (self.q1, self.q2, self.qs), (self.qm,), "same"
+        )
+
+    def test_invert(self):
+        self._test1(pnp.invert, (self.q1, self.q2, self.qs), (), "same")
+
+    def test_left_shift(self):
+        self._test2(
+            pnp.left_shift, self.q1, (self.qless, 2), (self.q1, self.q2, self.qs), "same"
+        )
+
+    def test_right_shift(self):
+        self._test2(
+            pnp.right_shift,
+            self.q1,
+            (self.qless, 2),
+            (self.q1, self.q2, self.qs),
+            "same",
+        )

From 62e5f238d7d0f15f58ee9fc0bfed688a04ac6141 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sat, 4 Jan 2025 21:53:19 +0000
Subject: [PATCH 02/49] tests

---
 src/pint_array/__init__.py |  12 +-
 tests/test_array.py        | 968 +------------------------------------
 2 files changed, 31 insertions(+), 949 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 019a635..dcbdc9b 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -610,7 +610,6 @@ def where(condition, x1, x2, /):
         "sin",
         "sinh",
         "square",
-        "sqrt",
         "tan",
         "tanh",
         "trunc",
@@ -624,6 +623,17 @@ def fun(x, /, *args, func_str=func_str, **kwargs):
             return ArrayUnitQuantity(magnitude, x.units)
 
         setattr(mod, func_str, fun)
+    
+    for func_str in ["sqrt"]:
+
+        def fun(x, /, *args, func_str=func_str, **kwargs):
+            x = asarray(x)
+            magnitude = xp.asarray(x.magnitude, copy=True)
+            magnitude = getattr(xp, func_str)(magnitude, *args, **kwargs)
+            return ArrayUnitQuantity(magnitude, x.units ** 0.5)
+
+        setattr(mod, func_str, fun)
+
 
     elementwise_two_arrays = [
         "add",
diff --git a/tests/test_array.py b/tests/test_array.py
index 4fac87d..4f0532b 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -54,7 +54,7 @@ def q_temperature(self):
 
     def assertNDArrayEqual(self, actual, desired):
         # Assert that the given arrays are equal, and are not Quantities
-        pnp.testing.assert_array_equal(actual, desired)
+        np.testing.assert_array_equal(actual, desired)
         assert not isinstance(actual, self.Q_)
         assert not isinstance(desired, self.Q_)
 
@@ -74,7 +74,7 @@ def test_zeros_like(self):
     def test_empty_like(self):
         ret = pnp.empty_like(self.q)
         assert ret.shape == (2, 2)
-        assert isinstance(ret, pnp.ndarray)
+        assert isinstance(ret, np.ndarray)
 
     # @helpers.requires_array_function_protocol()
     def test_full_like(self):
@@ -106,13 +106,6 @@ def test_reshape(self):
             self.q.reshape([1, 4]), [[1, 2, 3, 4]] * self.ureg.m
         )
 
-    def test_ravel(self):
-        helpers.assert_quantity_equal(self.q.ravel(), [1, 2, 3, 4] * self.ureg.m)
-
-    # @helpers.requires_array_function_protocol()
-    def test_ravel_numpy_func(self):
-        helpers.assert_quantity_equal(pnp.ravel(self.q), [1, 2, 3, 4] * self.ureg.m)
-
     # Transpose-like operations
 
     # @helpers.requires_array_function_protocol()
@@ -122,26 +115,9 @@ def test_moveaxis(self):
         )
 
     # @helpers.requires_array_function_protocol()
-    def test_rollaxis(self):
-        helpers.assert_quantity_equal(
-            pnp.rollaxis(self.q, 1), np.array([[1, 2], [3, 4]]).T * self.ureg.m
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_swapaxes(self):
-        helpers.assert_quantity_equal(
-            pnp.swapaxes(self.q, 1, 0), np.array([[1, 2], [3, 4]]).T * self.ureg.m
-        )
-
     def test_transpose(self):
         helpers.assert_quantity_equal(
-            self.q.transpose(), [[1, 3], [2, 4]] * self.ureg.m
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_transpose_numpy_func(self):
-        helpers.assert_quantity_equal(
-            pnp.transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
+            pnp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
         )
 
     # @helpers.requires_array_function_protocol()
@@ -152,38 +128,6 @@ def test_flip_numpy_func(self):
 
     # Changing number of dimensions
 
-    # @helpers.requires_array_function_protocol()
-    def test_atleast_1d(self):
-        actual = pnp.atleast_1d(self.Q_(0, self.ureg.degC), self.q.flatten())
-        expected = (self.Q_(np.array([0]), self.ureg.degC), self.q.flatten())
-        for ind_actual, ind_expected in zip(actual, expected):
-            helpers.assert_quantity_equal(ind_actual, ind_expected)
-        helpers.assert_quantity_equal(pnp.atleast_1d(self.q), self.q)
-
-    # @helpers.requires_array_function_protocol()
-    def test_atleast_2d(self):
-        actual = pnp.atleast_2d(self.Q_(0, self.ureg.degC), self.q.flatten())
-        expected = (
-            self.Q_(np.array([[0]]), self.ureg.degC),
-            np.array([[1, 2, 3, 4]]) * self.ureg.m,
-        )
-        for ind_actual, ind_expected in zip(actual, expected):
-            helpers.assert_quantity_equal(ind_actual, ind_expected)
-        helpers.assert_quantity_equal(pnp.atleast_2d(self.q), self.q)
-
-    # @helpers.requires_array_function_protocol()
-    def test_atleast_3d(self):
-        actual = pnp.atleast_3d(self.Q_(0, self.ureg.degC), self.q.flatten())
-        expected = (
-            self.Q_(np.array([[[0]]]), self.ureg.degC),
-            np.array([[[1], [2], [3], [4]]]) * self.ureg.m,
-        )
-        for ind_actual, ind_expected in zip(actual, expected):
-            helpers.assert_quantity_equal(ind_actual, ind_expected)
-        helpers.assert_quantity_equal(
-            pnp.atleast_3d(self.q), np.array([[[1], [2]], [[3], [4]]]) * self.ureg.m
-        )
-
     # @helpers.requires_array_function_protocol()
     def test_broadcast_to(self):
         helpers.assert_quantity_equal(
@@ -201,14 +145,14 @@ def test_expand_dims(self):
     def test_squeeze(self):
         helpers.assert_quantity_equal(pnp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
-            self.q.reshape([1, 4]).squeeze(), [1, 2, 3, 4] * self.ureg.m
+            pnp.squeeze(self.q.reshape([1, 4])), [1, 2, 3, 4] * self.ureg.m
         )
 
     # Changing number of dimensions
     # Joining arrays
     # @helpers.requires_array_function_protocol()
     def test_concat_stack(self, subtests):
-        for func in (pnp.concatenate, pnp.stack, pnp.hstack, pnp.vstack, pnp.dstack):
+        for func in (pnp.concat, pnp.stack):
             with subtests.test(func=func):
                 helpers.assert_quantity_equal(
                     func([self.q] * 2), self.Q_(func([self.q.m] * 2), self.ureg.m)
@@ -225,49 +169,6 @@ def test_concat_stack(self, subtests):
                 with pytest.raises(DimensionalityError):
                     func([nz.m, self.q])
 
-    # @helpers.requires_array_function_protocol()
-    def test_block_column_stack(self, subtests):
-        for func in (pnp.block, pnp.column_stack):
-            with subtests.test(func=func):
-                helpers.assert_quantity_equal(
-                    func([self.q[:, 0], self.q[:, 1]]),
-                    self.Q_(func([self.q[:, 0].m, self.q[:, 1].m]), self.ureg.m),
-                )
-
-                # One or more of the args is a bare array full of zeros or NaNs
-                helpers.assert_quantity_equal(
-                    func(
-                        [
-                            self.q_zero_or_nan[:, 0].m,
-                            self.q[:, 0],
-                            self.q_zero_or_nan[:, 1].m,
-                        ]
-                    ),
-                    self.Q_(
-                        func(
-                            [
-                                self.q_zero_or_nan[:, 0].m,
-                                self.q[:, 0].m,
-                                self.q_zero_or_nan[:, 1].m,
-                            ]
-                        ),
-                        self.ureg.m,
-                    ),
-                )
-                # One or more of the args is a bare array with at least one non-zero,
-                # non-NaN element
-                nz = self.q_zero_or_nan
-                nz.m[0, 0] = 1
-                with pytest.raises(DimensionalityError):
-                    func([nz[:, 0].m, self.q[:, 0]])
-
-    # @helpers.requires_array_function_protocol()
-    def test_append(self):
-        helpers.assert_quantity_equal(
-            pnp.append(self.q, [[0, 0]] * self.ureg.m, axis=0),
-            [[1, 2], [3, 4], [0, 0]] * self.ureg.m,
-        )
-
     def test_astype(self):
         actual = self.q.astype(pnp.float32)
         expected = self.Q_(np.array([[1.0, 2.0], [3.0, 4.0]], dtype=pnp.float32), "m")
@@ -301,37 +202,6 @@ def test_roll(self):
 
 class TestNumpyMathematicalFunctions(TestNumpyMethods):
     # https://www.numpy.org/devdocs/reference/routines.math.html
-    # Trigonometric functions
-    # @helpers.requires_array_function_protocol()
-    def test_unwrap(self):
-        helpers.assert_quantity_equal(
-            pnp.unwrap([0, 3 * pnp.pi] * self.ureg.radians), [0, pnp.pi]
-        )
-        helpers.assert_quantity_equal(
-            pnp.unwrap([0, 540] * self.ureg.deg), [0, 180] * self.ureg.deg
-        )
-
-    # Rounding
-
-    # @helpers.requires_array_function_protocol()
-    def test_fix(self):
-        helpers.assert_quantity_equal(pnp.fix(3.13 * self.ureg.m), 3.0 * self.ureg.m)
-        helpers.assert_quantity_equal(pnp.fix(3.0 * self.ureg.m), 3.0 * self.ureg.m)
-        helpers.assert_quantity_equal(
-            pnp.fix([2.1, 2.9, -2.1, -2.9] * self.ureg.m),
-            [2.0, 2.0, -2.0, -2.0] * self.ureg.m,
-        )
-
-    # Sums, products, differences
-
-    # @helpers.requires_array_function_protocol()
-    def test_prod(self):
-        axis = 0
-        where = [[True, False], [True, True]]
-
-        helpers.assert_quantity_equal(self.q.prod(), 24 * self.ureg.m**4)
-        helpers.assert_quantity_equal(self.q.prod(axis=axis), [3, 8] * self.ureg.m**2)
-        helpers.assert_quantity_equal(self.q.prod(where=where), 12 * self.ureg.m**3)
 
     # @helpers.requires_array_function_protocol()
     def test_prod_numpy_func(self):
@@ -354,150 +224,12 @@ def test_prod_numpy_func(self):
             pnp.prod(self.q, axis=axis, where=[True, False]), [3, 1] * self.ureg.m**2
         )
 
-    # @helpers.requires_array_function_protocol()
-    def test_nanprod_numpy_func(self):
-        helpers.assert_quantity_equal(pnp.nanprod(self.q_nan), 6 * self.ureg.m**3)
-        helpers.assert_quantity_equal(
-            pnp.nanprod(self.q_nan, axis=0), [3, 2] * self.ureg.m**2
-        )
-        helpers.assert_quantity_equal(
-            pnp.nanprod(self.q_nan, axis=1), [2, 3] * self.ureg.m**2
-        )
-
-    def test_sum(self):
-        assert self.q.sum() == 10 * self.ureg.m
-        helpers.assert_quantity_equal(self.q.sum(0), [4, 6] * self.ureg.m)
-        helpers.assert_quantity_equal(self.q.sum(1), [3, 7] * self.ureg.m)
-
     # @helpers.requires_array_function_protocol()
     def test_sum_numpy_func(self):
         helpers.assert_quantity_equal(pnp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
         with pytest.raises(OffsetUnitCalculusError):
             pnp.sum(self.q_temperature)
 
-    # @helpers.requires_array_function_protocol()
-    def test_nansum_numpy_func(self):
-        helpers.assert_quantity_equal(
-            pnp.nansum(self.q_nan, axis=0), [4, 2] * self.ureg.m
-        )
-
-    def test_cumprod(self):
-        with pytest.raises(DimensionalityError):
-            self.q.cumprod()
-        helpers.assert_quantity_equal((self.q / self.ureg.m).cumprod(), [1, 2, 6, 24])
-
-    # @helpers.requires_array_function_protocol()
-    def test_cumprod_numpy_func(self):
-        with pytest.raises(DimensionalityError):
-            pnp.cumprod(self.q)
-        helpers.assert_quantity_equal(pnp.cumprod(self.q / self.ureg.m), [1, 2, 6, 24])
-        helpers.assert_quantity_equal(
-            pnp.cumprod(self.q / self.ureg.m, axis=1), [[1, 2], [3, 12]]
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_nancumprod_numpy_func(self):
-        with pytest.raises(DimensionalityError):
-            pnp.nancumprod(self.q_nan)
-        helpers.assert_quantity_equal(
-            pnp.nancumprod(self.q_nan / self.ureg.m), [1, 2, 6, 6]
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_diff(self):
-        helpers.assert_quantity_equal(pnp.diff(self.q, 1), [[1], [1]] * self.ureg.m)
-        helpers.assert_quantity_equal(
-            pnp.diff(self.q_temperature, 1), [[1], [1]] * self.ureg.delta_degC
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_ediff1d(self):
-        helpers.assert_quantity_equal(pnp.ediff1d(self.q), [1, 1, 1] * self.ureg.m)
-        helpers.assert_quantity_equal(
-            pnp.ediff1d(self.q_temperature), [1, 1, 1] * self.ureg.delta_degC
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_gradient(self):
-        grad = pnp.gradient([[1, 1], [3, 4]] * self.ureg.m, 1 * self.ureg.J)
-        helpers.assert_quantity_equal(
-            grad[0], [[2.0, 3.0], [2.0, 3.0]] * self.ureg.m / self.ureg.J
-        )
-        helpers.assert_quantity_equal(
-            grad[1], [[0.0, 0.0], [1.0, 1.0]] * self.ureg.m / self.ureg.J
-        )
-
-        grad = pnp.gradient(self.Q_([[1, 1], [3, 4]], self.ureg.degC), 1 * self.ureg.J)
-        helpers.assert_quantity_equal(
-            grad[0], [[2.0, 3.0], [2.0, 3.0]] * self.ureg.delta_degC / self.ureg.J
-        )
-        helpers.assert_quantity_equal(
-            grad[1], [[0.0, 0.0], [1.0, 1.0]] * self.ureg.delta_degC / self.ureg.J
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_cross(self):
-        a = [[3, -3, 1]] * self.ureg.kPa
-        b = [[4, 9, 2]] * self.ureg.m**2
-        helpers.assert_quantity_equal(
-            pnp.cross(a, b), [[-15, -2, 39]] * self.ureg.kPa * self.ureg.m**2
-        )
-
-    # NP2: Remove this when we only support np>=2.0
-    # @helpers.requires_array_function_protocol()
-    def test_trapz(self):
-        helpers.assert_quantity_equal(
-            pnp.trapz([1.0, 2.0, 3.0, 4.0] * self.ureg.J, dx=1 * self.ureg.m),
-            7.5 * self.ureg.J * self.ureg.m,
-        )
-
-    # @helpers.requires_array_function_protocol()
-    # NP2: Remove this when we only support np>=2.0
-    # trapezoid added in numpy 2.0
-    # @helpers.requires_numpy_at_least("2.0")
-    def test_trapezoid(self):
-        helpers.assert_quantity_equal(
-            pnp.trapezoid([1.0, 2.0, 3.0, 4.0] * self.ureg.J, dx=1 * self.ureg.m),
-            7.5 * self.ureg.J * self.ureg.m,
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_dot(self):
-        helpers.assert_quantity_equal(
-            self.q.ravel().dot(np.array([1, 0, 0, 1])), 5 * self.ureg.m
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_dot_numpy_func(self):
-        helpers.assert_quantity_equal(
-            pnp.dot(self.q.ravel(), [0, 0, 1, 0] * self.ureg.dimensionless),
-            3 * self.ureg.m,
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_einsum(self):
-        a = pnp.arange(25).reshape(5, 5) * self.ureg.m
-        b = pnp.arange(5) * self.ureg.m
-        helpers.assert_quantity_equal(pnp.einsum("ii", a), 60 * self.ureg.m)
-        helpers.assert_quantity_equal(
-            pnp.einsum("ii->i", a), np.array([0, 6, 12, 18, 24]) * self.ureg.m
-        )
-        helpers.assert_quantity_equal(pnp.einsum("i,i", b, b), 30 * self.ureg.m**2)
-        helpers.assert_quantity_equal(
-            pnp.einsum("ij,j", a, b),
-            np.array([30, 80, 130, 180, 230]) * self.ureg.m**2,
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_solve(self):
-        A = self.q
-        b = [[3], [7]] * self.ureg.s
-        x = pnp.linalg.solve(A, b)
-
-        helpers.assert_quantity_almost_equal(x, self.Q_([[1], [1]], "s / m"))
-
-        helpers.assert_quantity_almost_equal(pnp.dot(A, x), b)
-
     # Arithmetic operations
     def test_addition_with_scalar(self):
         a = np.array([0, 1, 2])
@@ -521,7 +253,7 @@ def test_power(self):
         arr = np.array(range(3), dtype=float)
         q = self.Q_(arr, "meter")
 
-        for op_ in (op.pow, op.ipow, pnp.power):
+        for op_ in [pnp.pow]:
             q_cp = copy.copy(q)
             with pytest.raises(DimensionalityError):
                 op_(2.0, q_cp)
@@ -536,7 +268,7 @@ def test_power(self):
                 op_(q_cp, q2_cp)
 
         helpers.assert_quantity_equal(
-            pnp.power(self.q, self.Q_(2)), self.Q_([[1, 4], [9, 16]], "m**2")
+            pnp.pow(self.q, self.Q_(2)), self.Q_([[1, 4], [9, 16]], "m**2")
         )
         helpers.assert_quantity_equal(
             self.q ** self.Q_(2), self.Q_([[1, 4], [9, 16]], "m**2")
@@ -547,10 +279,6 @@ def test_sqrt(self):
         q = self.Q_(100, "m**2")
         helpers.assert_quantity_equal(pnp.sqrt(q), self.Q_(10, "m"))
 
-    def test_cbrt(self):
-        q = self.Q_(1000, "m**3")
-        helpers.assert_quantity_equal(pnp.cbrt(q), self.Q_(10, "m"))
-
     @pytest.mark.xfail
     # @helpers.requires_numpy
     def test_exponentiation_array_exp_2(self):
@@ -572,109 +300,27 @@ def test_exponentiation_array_exp_2(self):
 
 
 class TestNumpyUnclassified(TestNumpyMethods):
-    def test_tolist(self):
-        with pytest.raises(AttributeError):
-            (5 * self.ureg.m).tolist()
-
-        assert self.q.tolist() == [
-            [1 * self.ureg.m, 2 * self.ureg.m],
-            [3 * self.ureg.m, 4 * self.ureg.m],
-        ]
-
-    def test_fill(self):
-        tmp = self.q
-        tmp.fill(6 * self.ureg.ft)
-        helpers.assert_quantity_equal(tmp, [[6, 6], [6, 6]] * self.ureg.ft)
-        tmp.fill(5 * self.ureg.m)
-        helpers.assert_quantity_equal(tmp, [[5, 5], [5, 5]] * self.ureg.m)
-
-    def test_take(self):
-        helpers.assert_quantity_equal(self.q.take([0, 1, 2, 3]), self.q.flatten())
-
-    def test_put(self):
-        q = [1.0, 2.0, 3.0, 4.0] * self.ureg.m
-        q.put([0, 2], [10.0, 20.0] * self.ureg.m)
-        helpers.assert_quantity_equal(q, [10.0, 2.0, 20.0, 4.0] * self.ureg.m)
-
-        q = [1.0, 2.0, 3.0, 4.0] * self.ureg.m
-        q.put([0, 2], [1.0, 2.0] * self.ureg.mm)
-        helpers.assert_quantity_equal(q, [0.001, 2.0, 0.002, 4.0] * self.ureg.m)
-
-        q = [1.0, 2.0, 3.0, 4.0] * self.ureg.m / self.ureg.mm
-        q.put([0, 2], [1.0, 2.0])
-        helpers.assert_quantity_equal(
-            q, [0.001, 2.0, 0.002, 4.0] * self.ureg.m / self.ureg.mm
-        )
-
-        q = [1.0, 2.0, 3.0, 4.0] * self.ureg.m
-        with pytest.raises(DimensionalityError):
-            q.put([0, 2], [4.0, 6.0] * self.ureg.J)
-        with pytest.raises(DimensionalityError):
-            q.put([0, 2], [4.0, 6.0])
 
     def test_repeat(self):
         helpers.assert_quantity_equal(
-            self.q.repeat(2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
+            pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
         )
 
-    def test_sort(self):
-        q = [4, 5, 2, 3, 1, 6] * self.ureg.m
-        q.sort()
-        helpers.assert_quantity_equal(q, [1, 2, 3, 4, 5, 6] * self.ureg.m)
-
     # @helpers.requires_array_function_protocol()
     def test_sort_numpy_func(self):
         q = [4, 5, 2, 3, 1, 6] * self.ureg.m
         helpers.assert_quantity_equal(pnp.sort(q), [1, 2, 3, 4, 5, 6] * self.ureg.m)
 
-    def test_argsort(self):
-        q = [1, 4, 5, 6, 2, 9] * self.ureg.MeV
-        self.assertNDArrayEqual(q.argsort(), [0, 4, 1, 2, 3, 5])
-
     # @helpers.requires_array_function_protocol()
     def test_argsort_numpy_func(self):
         self.assertNDArrayEqual(pnp.argsort(self.q, axis=0), np.array([[0, 0], [1, 1]]))
 
-    def test_diagonal(self):
-        q = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] * self.ureg.m
-        helpers.assert_quantity_equal(q.diagonal(offset=1), [2, 3] * self.ureg.m)
-
-    # @helpers.requires_array_function_protocol()
-    def test_diagonal_numpy_func(self):
-        q = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] * self.ureg.m
-        helpers.assert_quantity_equal(pnp.diagonal(q, offset=-1), [1, 2] * self.ureg.m)
-
-    def test_compress(self):
-        helpers.assert_quantity_equal(
-            self.q.compress([False, True], axis=0), [[3, 4]] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            self.q.compress([False, True], axis=1), [[2], [4]] * self.ureg.m
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_compress_nep18(self):
-        helpers.assert_quantity_equal(
-            pnp.compress([False, True], self.q, axis=1), [[2], [4]] * self.ureg.m
-        )
-
-    def test_searchsorted(self):
-        q = self.q.flatten()
-        self.assertNDArrayEqual(q.searchsorted([1.5, 2.5] * self.ureg.m), [1, 2])
-        q = self.q.flatten()
-        with pytest.raises(DimensionalityError):
-            q.searchsorted([1.5, 2.5])
-
     # @helpers.requires_array_function_protocol()
     def test_searchsorted_numpy_func(self):
         """Test searchsorted as numpy function."""
         q = self.q.flatten()
         self.assertNDArrayEqual(pnp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
 
-    def test_nonzero(self):
-        q = [1, 0, 5, 6, 0, 9] * self.ureg.m
-        self.assertNDArrayEqual(q.nonzero()[0], [0, 2, 3, 5])
-
     # @helpers.requires_array_function_protocol()
     def test_nonzero_numpy_func(self):
         q = [1, 0, 5, 6, 0, 9] * self.ureg.m
@@ -694,14 +340,6 @@ def test_all_numpy_func(self):
         with pytest.raises(ValueError):
             pnp.all(self.q_temperature)
 
-    # @helpers.requires_array_function_protocol()
-    def test_count_nonzero_numpy_func(self):
-        q = [1, 0, 5, 6, 0, 9] * self.ureg.m
-        assert pnp.count_nonzero(q) == 4
-
-    def test_max(self):
-        assert self.q.max() == 4 * self.ureg.m
-
     def test_max_numpy_func(self):
         assert pnp.max(self.q) == 4 * self.ureg.m
 
@@ -716,29 +354,15 @@ def test_max_with_initial_arg(self):
             [[3, 3], [3, 4]] * self.ureg.m,
         )
 
-    # @helpers.requires_array_function_protocol()
-    def test_nanmax(self):
-        assert pnp.nanmax(self.q_nan) == 3 * self.ureg.m
-
-    def test_argmax(self):
-        assert self.q.argmax() == 3
-
     # @helpers.requires_array_function_protocol()
     def test_argmax_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmax(self.q, axis=0), np.array([1, 1]))
 
-    # @helpers.requires_array_function_protocol()
-    def test_nanargmax_numpy_func(self):
-        self.assertNDArrayEqual(pnp.nanargmax(self.q_nan, axis=0), np.array([1, 0]))
-
     def test_maximum(self):
         helpers.assert_quantity_equal(
             pnp.maximum(self.q, self.Q_([0, 5], "m")), self.Q_([[1, 5], [3, 5]], "m")
         )
 
-    def test_min(self):
-        assert self.q.min() == 1 * self.ureg.m
-
     # @helpers.requires_array_function_protocol()
     def test_min_numpy_func(self):
         assert pnp.min(self.q) == 1 * self.ureg.m
@@ -754,162 +378,57 @@ def test_min_with_initial_arg(self):
             [[1, 2], [3, 3]] * self.ureg.m,
         )
 
-    # @helpers.requires_array_function_protocol()
-    def test_nanmin(self):
-        assert pnp.nanmin(self.q_nan) == 1 * self.ureg.m
-
-    def test_argmin(self):
-        assert self.q.argmin() == 0
-
     # @helpers.requires_array_function_protocol()
     def test_argmin_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmin(self.q, axis=0), np.array([0, 0]))
 
-    # @helpers.requires_array_function_protocol()
-    def test_nanargmin_numpy_func(self):
-        self.assertNDArrayEqual(pnp.nanargmin(self.q_nan, axis=0), np.array([0, 0]))
-
     def test_minimum(self):
         helpers.assert_quantity_equal(
             pnp.minimum(self.q, self.Q_([0, 5], "m")), self.Q_([[0, 2], [0, 4]], "m")
         )
 
-    # NP2: Can remove Q_(arr).ptp test when we only support numpy>=2
-    def test_ptp(self):
-        if not pnp.lib.NumpyVersion(pnp.__version__) >= "2.0.0b1":
-            assert self.q.ptp() == 3 * self.ureg.m
-
-    # NP2: Keep this test for numpy>=2, it's only arr.ptp() that is deprecated
-    # @helpers.requires_array_function_protocol()
-    def test_ptp_numpy_func(self):
-        helpers.assert_quantity_equal(pnp.ptp(self.q, axis=0), [2, 2] * self.ureg.m)
-
-    def test_clip(self):
-        helpers.assert_quantity_equal(
-            self.q.clip(max=2 * self.ureg.m), [[1, 2], [2, 2]] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            self.q.clip(min=3 * self.ureg.m), [[3, 3], [3, 4]] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            self.q.clip(min=2 * self.ureg.m, max=3 * self.ureg.m),
-            [[2, 2], [3, 3]] * self.ureg.m,
-        )
-        helpers.assert_quantity_equal(
-            self.q.clip(3 * self.ureg.m, None), [[3, 3], [3, 4]] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            self.q.clip(3 * self.ureg.m), [[3, 3], [3, 4]] * self.ureg.m
-        )
-        with pytest.raises(DimensionalityError):
-            self.q.clip(self.ureg.J)
-        with pytest.raises(DimensionalityError):
-            self.q.clip(1)
-
     # @helpers.requires_array_function_protocol()
     def test_clip_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
         )
 
-    def test_round(self):
-        q = [1, 1.33, 5.67, 22] * self.ureg.m
-        helpers.assert_quantity_equal(q.round(0), [1, 1, 6, 22] * self.ureg.m)
-        helpers.assert_quantity_equal(q.round(-1), [0, 0, 10, 20] * self.ureg.m)
-        helpers.assert_quantity_equal(q.round(1), [1, 1.3, 5.7, 22] * self.ureg.m)
-
     # @helpers.requires_array_function_protocol()
     def test_round_numpy_func(self):
-        helpers.assert_quantity_equal(
-            pnp.around(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
-        )
         helpers.assert_quantity_equal(
             pnp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
         )
 
-    def test_trace(self):
-        assert self.q.trace() == (1 + 4) * self.ureg.m
-
-    def test_cumsum(self):
-        helpers.assert_quantity_equal(self.q.cumsum(), [1, 3, 6, 10] * self.ureg.m)
-
-    # @helpers.requires_array_function_protocol()
-    def test_cumsum_numpy_func(self):
-        helpers.assert_quantity_equal(
-            pnp.cumsum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
-        )
-
     # @helpers.requires_array_function_protocol()
-    def test_nancumsum_numpy_func(self):
+    def test_cumulative_sum(self):
         helpers.assert_quantity_equal(
-            pnp.nancumsum(self.q_nan, axis=0), [[1, 2], [4, 2]] * self.ureg.m
+            pnp.cumulative_sum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
         )
 
-    def test_mean(self):
-        assert self.q.mean() == 2.5 * self.ureg.m
-
     # @helpers.requires_array_function_protocol()
     def test_mean_numpy_func(self):
         assert pnp.mean(self.q) == 2.5 * self.ureg.m
         assert pnp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
 
-    # @helpers.requires_array_function_protocol()
-    def test_nanmean_numpy_func(self):
-        assert pnp.nanmean(self.q_nan) == 2 * self.ureg.m
-
-    # @helpers.requires_array_function_protocol()
-    def test_average_numpy_func(self):
-        helpers.assert_quantity_almost_equal(
-            pnp.average(self.q, axis=0, weights=[1, 2]),
-            [2.33333, 3.33333] * self.ureg.m,
-            rtol=1e-5,
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_median_numpy_func(self):
-        assert pnp.median(self.q) == 2.5 * self.ureg.m
-
-    # @helpers.requires_array_function_protocol()
-    def test_nanmedian_numpy_func(self):
-        assert pnp.nanmedian(self.q_nan) == 2 * self.ureg.m
-
-    def test_var(self):
-        assert self.q.var() == 1.25 * self.ureg.m**2
-
     # @helpers.requires_array_function_protocol()
     def test_var_numpy_func(self):
         assert pnp.var(self.q) == 1.25 * self.ureg.m**2
-
-    # @helpers.requires_array_function_protocol()
-    def test_nanvar_numpy_func(self):
-        helpers.assert_quantity_almost_equal(
-            pnp.nanvar(self.q_nan), 0.66667 * self.ureg.m**2, rtol=1e-5
-        )
-
-    def test_std(self):
-        helpers.assert_quantity_almost_equal(
-            self.q.std(), 1.11803 * self.ureg.m, rtol=1e-5
-        )
+        assert pnp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
 
     # @helpers.requires_array_function_protocol()
     def test_std_numpy_func(self):
         helpers.assert_quantity_almost_equal(
             pnp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
         )
-        with pytest.raises(OffsetUnitCalculusError):
-            pnp.std(self.q_temperature)
+        helpers.assert_quantity_almost_equal(
+            pnp.std(self.q_temperature), 1.11803 * self.ureg.delta_degC, rtol=1e-5
+        )
 
     def test_cumprod(self):
         with pytest.raises(DimensionalityError):
             self.q.cumprod()
         helpers.assert_quantity_equal((self.q / self.ureg.m).cumprod(), [1, 2, 6, 24])
 
-    # @helpers.requires_array_function_protocol()
-    def test_nanstd_numpy_func(self):
-        helpers.assert_quantity_almost_equal(
-            pnp.nanstd(self.q_nan), 0.81650 * self.ureg.m, rtol=1e-5
-        )
-
     def test_conj(self):
         helpers.assert_quantity_equal((self.q * (1 + 1j)).conj(), self.q * (1 - 1j))
         helpers.assert_quantity_equal(
@@ -930,7 +449,7 @@ def test_setitem(self):
         with pytest.raises(DimensionalityError):
             self.q[0] = 1
         with pytest.raises(DimensionalityError):
-            self.q[0] = pnp.ndarray([1, 2])
+            self.q[0] = np.ndarray([1, 2])
         with pytest.raises(DimensionalityError):
             self.q[0] = 1 * self.ureg.J
 
@@ -957,40 +476,6 @@ def test_setitem(self):
         q[0] = 1.0
         helpers.assert_quantity_equal(q, [0.001, 1, 2, 3] * self.ureg.m / self.ureg.mm)
 
-        # Check that this properly masks the first item without warning
-        q = self.ureg.Quantity(
-            pnp.ma.array([0.0, 1.0, 2.0, 3.0], mask=[False, True, False, False]), "m"
-        )
-        with warnings.catch_warnings(record=True) as w:
-            q[0] = pnp.ma.masked
-            # Check for no warnings
-            assert not w
-            assert q.mask[0]
-
-    def test_setitem_mixed_masked(self):
-        masked = pnp.ma.array(
-            [
-                1,
-                2,
-            ],
-            mask=[True, False],
-        )
-        q = self.Q_(pnp.ones(shape=(2,)), "m")
-        with pytest.raises(DimensionalityError):
-            q[:] = masked
-
-        masked_q = self.Q_(masked, "mm")
-        q[:] = masked_q
-        helpers.assert_quantity_equal(q, [1.0, 0.002] * self.ureg.m)
-
-    def test_iterator(self):
-        for q, v in zip(self.q.flatten(), [1, 2, 3, 4]):
-            assert q == v * self.ureg.m
-
-    def test_iterable(self):
-        assert pnp.iterable(self.q)
-        assert not pnp.iterable(1 * self.ureg.m)
-
     def test_reversible_op(self):
         """ """
         x = self.q.magnitude
@@ -1011,8 +496,8 @@ def test_pickle(self, subtests):
     def test_equal(self):
         x = self.q.magnitude
         u = self.Q_(pnp.ones(x.shape))
-        true = pnp.ones_like(x, dtype=pnp.bool_)
-        false = pnp.zeros_like(x, dtype=pnp.bool_)
+        true = pnp.ones_like(x, dtype=np.bool_)
+        false = pnp.zeros_like(x, dtype=np.bool_)
 
         helpers.assert_quantity_equal(u, u)
         helpers.assert_quantity_equal(u == u, u.magnitude == u.magnitude)
@@ -1029,12 +514,7 @@ def test_equal(self):
         self.assertNDArrayEqual(v == w, false)
         self.assertNDArrayEqual(v == w.to("mm"), false)
         self.assertNDArrayEqual(u == v, false)
-
-    def test_shape(self):
-        u = self.Q_(pnp.arange(12))
-        u.shape = 4, 3
-        assert u.magnitude.shape == (4, 3)
-
+    
     def test_dtype(self):
         u = self.Q_(pnp.arange(12, dtype="uint32"))
 
@@ -1042,37 +522,11 @@ def test_dtype(self):
 
     # @helpers.requires_array_function_protocol()
     def test_shape_numpy_func(self):
-        assert pnp.shape(self.q) == (2, 2)
-
-    # @helpers.requires_array_function_protocol()
-    def test_len_numpy_func(self):
-        assert len(self.q) == 2
+        assert pnp.asarray(self.q).shape == (2, 2)
 
     # @helpers.requires_array_function_protocol()
     def test_ndim_numpy_func(self):
-        assert pnp.ndim(self.q) == 2
-
-    # @helpers.requires_array_function_protocol()
-    def test_copy_numpy_func(self):
-        q_copy = pnp.copy(self.q)
-        helpers.assert_quantity_equal(self.q, q_copy)
-        assert self.q is not q_copy
-
-    # @helpers.requires_array_function_protocol()
-    def test_trim_zeros_numpy_func(self):
-        q = [0, 4, 3, 0, 2, 2, 0, 0, 0] * self.ureg.m
-        helpers.assert_quantity_equal(pnp.trim_zeros(q), [4, 3, 0, 2, 2] * self.ureg.m)
-
-    # @helpers.requires_array_function_protocol()
-    def test_result_type_numpy_func(self):
-        assert pnp.result_type(self.q) == pnp.dtype("int")
-
-    # @helpers.requires_array_function_protocol()
-    def test_nan_to_num_numpy_func(self):
-        helpers.assert_quantity_equal(
-            pnp.nan_to_num(self.q_nan, nan=-999 * self.ureg.mm),
-            [[1, 2], [3, -0.999]] * self.ureg.m,
-        )
+        assert pnp.asarray(self.q).ndim == 2
 
     # @helpers.requires_array_function_protocol()
     def test_meshgrid_numpy_func(self):
@@ -1082,41 +536,6 @@ def test_meshgrid_numpy_func(self):
         helpers.assert_quantity_equal(xx, [[1, 2], [1, 2], [1, 2]] * self.ureg.m)
         helpers.assert_quantity_equal(yy, [[0, 0], [50, 50], [100, 100]] * self.ureg.mm)
 
-    # @helpers.requires_array_function_protocol()
-    def test_isclose_numpy_func(self):
-        q2 = [[1000.05, 2000], [3000.00007, 4001]] * self.ureg.mm
-        self.assertNDArrayEqual(
-            pnp.isclose(self.q, q2), np.array([[False, True], [True, False]])
-        )
-        self.assertNDArrayEqual(
-            pnp.isclose(self.q, q2, atol=1e-5 * self.ureg.mm, rtol=1e-7),
-            np.array([[False, True], [True, False]]),
-        )
-        self.assertNDArrayEqual(
-            pnp.isclose(self.q, q2, atol=1e-5, rtol=1e-7),
-            np.array([[False, True], [True, False]]),
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_interp_numpy_func(self):
-        x = [1, 4] * self.ureg.m
-        xp = pnp.linspace(0, 3, 5) * self.ureg.m
-        fp = self.Q_([0, 5, 10, 15, 20], self.ureg.degC)
-        helpers.assert_quantity_almost_equal(
-            pnp.interp(x, xp, fp), self.Q_([6.66667, 20.0], self.ureg.degC), rtol=1e-5
-        )
-
-        x_ = np.array([1, 4])
-        xp_ = pnp.linspace(0, 3, 5)
-        fp_ = [0, 5, 10, 15, 20]
-
-        helpers.assert_quantity_almost_equal(
-            pnp.interp(x_, xp_, fp), self.Q_([6.6667, 20.0], self.ureg.degC), rtol=1e-5
-        )
-        helpers.assert_quantity_almost_equal(
-            pnp.interp(x, xp, fp_), [6.6667, 20.0], rtol=1e-5
-        )
-
     def test_comparisons(self):
         self.assertNDArrayEqual(
             self.q > 2 * self.ureg.m, np.array([[False, False], [True, True]])
@@ -1174,355 +593,8 @@ def test_where(self):
                 self.ureg.Quantity([-1, 0, 1], "degC"), [1, 2, 1] * self.ureg.s, pnp.nan
             )
 
-    # @helpers.requires_array_function_protocol()
-    def test_fabs(self):
-        helpers.assert_quantity_equal(
-            pnp.fabs(self.q - 2 * self.ureg.m), self.Q_([[1, 0], [1, 2]], "m")
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_isin(self):
-        self.assertNDArrayEqual(
-            pnp.isin(self.q, self.Q_([0, 2, 4], "m")),
-            np.array([[False, True], [False, True]]),
-        )
-        self.assertNDArrayEqual(
-            pnp.isin(self.q, self.Q_([0, 2, 4], "J")),
-            np.array([[False, False], [False, False]]),
-        )
-        self.assertNDArrayEqual(
-            pnp.isin(self.q, [self.Q_(2, "m"), self.Q_(4, "J")]),
-            np.array([[False, True], [False, False]]),
-        )
-        self.assertNDArrayEqual(
-            pnp.isin(self.q, self.q.m), np.array([[False, False], [False, False]])
-        )
-        self.assertNDArrayEqual(
-            pnp.isin(self.q / self.ureg.cm, [1, 3]),
-            np.array([[True, False], [True, False]]),
-        )
-        with pytest.raises(ValueError):
-            pnp.isin(self.q.m, self.q)
-
-    # @helpers.requires_array_function_protocol()
-    def test_percentile(self):
-        helpers.assert_quantity_equal(pnp.percentile(self.q, 25), self.Q_(1.75, "m"))
-
-    # @helpers.requires_array_function_protocol()
-    def test_nanpercentile(self):
-        helpers.assert_quantity_equal(
-            pnp.nanpercentile(self.q_nan, 25), self.Q_(1.5, "m")
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_quantile(self):
-        helpers.assert_quantity_equal(pnp.quantile(self.q, 0.25), self.Q_(1.75, "m"))
-
-    # @helpers.requires_array_function_protocol()
-    def test_nanquantile(self):
-        helpers.assert_quantity_equal(
-            pnp.nanquantile(self.q_nan, 0.25), self.Q_(1.5, "m")
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_copyto(self):
-        a = self.q.m
-        q = copy.copy(self.q)
-        pnp.copyto(q, 2 * q, where=[True, False])
-        helpers.assert_quantity_equal(q, self.Q_([[2, 2], [6, 4]], "m"))
-        pnp.copyto(q, 0, where=[[False, False], [True, False]])
-        helpers.assert_quantity_equal(q, self.Q_([[2, 2], [0, 4]], "m"))
-        pnp.copyto(a, q)
-        self.assertNDArrayEqual(a, np.array([[2, 2], [0, 4]]))
-
     # @helpers.requires_array_function_protocol()
     def test_tile(self):
         helpers.assert_quantity_equal(
             pnp.tile(self.q, 2), np.array([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m
         )
-
-    # @helpers.requires_numpy_at_least("1.20")
-    # @helpers.requires_array_function_protocol()
-    def test_sliding_window_view(self):
-        q = self.Q_([[1, 2, 2, 1], [2, 1, 1, 2], [1, 2, 2, 1]], "m")
-        actual = pnp.lib.stride_tricks.sliding_window_view(q, window_shape=(3, 3))
-        expected = self.Q_(
-            [[[[1, 2, 2], [2, 1, 1], [1, 2, 2]], [[2, 2, 1], [1, 1, 2], [2, 2, 1]]]],
-            "m",
-        )
-        helpers.assert_quantity_equal(actual, expected)
-
-    # @helpers.requires_array_function_protocol()
-    def test_rot90(self):
-        helpers.assert_quantity_equal(
-            pnp.rot90(self.q), np.array([[2, 4], [1, 3]]) * self.ureg.m
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_insert(self):
-        helpers.assert_quantity_equal(
-            pnp.insert(self.q, 1, 0 * self.ureg.m, axis=1),
-            np.array([[1, 0, 2], [3, 0, 4]]) * self.ureg.m,
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_delete(self):
-        q = self.Q_(np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]), "m")
-        helpers.assert_quantity_equal(
-            pnp.delete(q, 1, axis=0),
-            np.array([[1, 2, 3, 4], [9, 10, 11, 12]]) * self.ureg.m,
-        )
-
-        helpers.assert_quantity_equal(
-            pnp.delete(q, pnp.s_[::2], 1),
-            np.array([[2, 4], [6, 8], [10, 12]]) * self.ureg.m,
-        )
-
-        helpers.assert_quantity_equal(
-            pnp.delete(q, [1, 3, 5], None),
-            np.array([1, 3, 5, 7, 8, 9, 10, 11, 12]) * self.ureg.m,
-        )
-
-    def test_ndarray_downcast(self):
-        with pytest.warns(UnitStrippedWarning):
-            pnp.asarray(self.q)
-
-    def test_ndarray_downcast_with_dtype(self):
-        with pytest.warns(UnitStrippedWarning):
-            qarr = pnp.asarray(self.q, dtype=pnp.float64)
-            assert qarr.dtype == pnp.float64
-
-    def test_array_protocol_unavailable(self):
-        for attr in ("__array_struct__", "__array_interface__"):
-            with pytest.raises(AttributeError):
-                getattr(self.q, attr)
-
-    # @helpers.requires_array_function_protocol()
-    def test_resize(self):
-        helpers.assert_quantity_equal(
-            pnp.resize(self.q, (2, 4)), [[1, 2, 3, 4], [1, 2, 3, 4]] * self.ureg.m
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_pad(self):
-        # Tests reproduced with modification from NumPy documentation
-        a = [1, 2, 3, 4, 5] * self.ureg.m
-        b = self.Q_([4.0, 6.0, 8.0, 9.0, -3.0], "degC")
-
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2, 3), "constant"), [0, 0, 1, 2, 3, 4, 5, 0, 0, 0] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2, 3), "constant", constant_values=(0, 600 * self.ureg.cm)),
-            [0, 0, 1, 2, 3, 4, 5, 6, 6, 6] * self.ureg.m,
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(
-                b, (2, 1), "constant", constant_values=(pnp.nan, self.Q_(10, "degC"))
-            ),
-            self.Q_([pnp.nan, pnp.nan, 4, 6, 8, 9, -3, 10], "degC"),
-        )
-        with pytest.raises(DimensionalityError):
-            pnp.pad(a, (2, 3), "constant", constant_values=4)
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2, 3), "edge"), [1, 1, 1, 2, 3, 4, 5, 5, 5, 5] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2, 3), "linear_ramp"),
-            [0, 0, 1, 2, 3, 4, 5, 3, 1, 0] * self.ureg.m,
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2, 3), "linear_ramp", end_values=(5, -4) * self.ureg.m),
-            [5, 3, 1, 2, 3, 4, 5, 2, -1, -4] * self.ureg.m,
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2,), "maximum"), [5, 5, 1, 2, 3, 4, 5, 5, 5] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2,), "mean"), [3, 3, 1, 2, 3, 4, 5, 3, 3] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2,), "median"), [3, 3, 1, 2, 3, 4, 5, 3, 3] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(self.q, ((3, 2), (2, 3)), "minimum"),
-            [
-                [1, 1, 1, 2, 1, 1, 1],
-                [1, 1, 1, 2, 1, 1, 1],
-                [1, 1, 1, 2, 1, 1, 1],
-                [1, 1, 1, 2, 1, 1, 1],
-                [3, 3, 3, 4, 3, 3, 3],
-                [1, 1, 1, 2, 1, 1, 1],
-                [1, 1, 1, 2, 1, 1, 1],
-            ]
-            * self.ureg.m,
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2, 3), "reflect"), [3, 2, 1, 2, 3, 4, 5, 4, 3, 2] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2, 3), "reflect", reflect_type="odd"),
-            [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8] * self.ureg.m,
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2, 3), "symmetric"), [2, 1, 1, 2, 3, 4, 5, 5, 4, 3] * self.ureg.m
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2, 3), "symmetric", reflect_type="odd"),
-            [0, 1, 1, 2, 3, 4, 5, 5, 6, 7] * self.ureg.m,
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(a, (2, 3), "wrap"), [4, 5, 1, 2, 3, 4, 5, 1, 2, 3] * self.ureg.m
-        )
-
-        def pad_with(vector, pad_width, iaxis, kwargs):
-            pad_value = kwargs.get("padder", 10)
-            vector[: pad_width[0]] = pad_value
-            vector[-pad_width[1] :] = pad_value
-
-        b = self.Q_(pnp.arange(6).reshape((2, 3)), "degC")
-        helpers.assert_quantity_equal(
-            pnp.pad(b, 2, pad_with),
-            self.Q_(
-                [
-                    [10, 10, 10, 10, 10, 10, 10],
-                    [10, 10, 10, 10, 10, 10, 10],
-                    [10, 10, 0, 1, 2, 10, 10],
-                    [10, 10, 3, 4, 5, 10, 10],
-                    [10, 10, 10, 10, 10, 10, 10],
-                    [10, 10, 10, 10, 10, 10, 10],
-                ],
-                "degC",
-            ),
-        )
-        helpers.assert_quantity_equal(
-            pnp.pad(b, 2, pad_with, padder=100),
-            self.Q_(
-                [
-                    [100, 100, 100, 100, 100, 100, 100],
-                    [100, 100, 100, 100, 100, 100, 100],
-                    [100, 100, 0, 1, 2, 100, 100],
-                    [100, 100, 3, 4, 5, 100, 100],
-                    [100, 100, 100, 100, 100, 100, 100],
-                    [100, 100, 100, 100, 100, 100, 100],
-                ],
-                "degC",
-            ),
-        )  # Note: Does not support Quantity pad_with vectorized callable use
-
-    # @helpers.requires_array_function_protocol()
-    def test_allclose(self):
-        assert pnp.allclose([1e10, 1e-8] * self.ureg.m, [1.00001e10, 1e-9] * self.ureg.m)
-        assert pnp.allclose(
-            [1e10, 1e-8] * self.ureg.m, [1.00001e13, 1e-6] * self.ureg.mm
-        )
-        assert not pnp.allclose(
-            [1e10, 1e-8] * self.ureg.m, [1.00001e10, 1e-9] * self.ureg.mm
-        )
-        assert pnp.allclose(
-            [1e10, 1e-8] * self.ureg.m,
-            [1.00001e10, 1e-9] * self.ureg.m,
-            atol=1e-8 * self.ureg.m,
-        )
-
-        assert not pnp.allclose([1.0, pnp.nan] * self.ureg.m, [1.0, pnp.nan] * self.ureg.m)
-
-        assert pnp.allclose(
-            [1.0, pnp.nan] * self.ureg.m, [1.0, pnp.nan] * self.ureg.m, equal_nan=True
-        )
-
-        assert pnp.allclose(
-            [1e10, 1e-8] * self.ureg.m, [1.00001e10, 1e-9] * self.ureg.m, atol=1e-8
-        )
-
-        with pytest.raises(DimensionalityError):
-            assert pnp.allclose(
-                [1e10, 1e-8] * self.ureg.m,
-                [1.00001e10, 1e-9] * self.ureg.m,
-                atol=1e-8 * self.ureg.s,
-            )
-
-    # @helpers.requires_array_function_protocol()
-    def test_intersect1d(self):
-        helpers.assert_quantity_equal(
-            pnp.intersect1d([1, 3, 4, 3] * self.ureg.m, [3, 1, 2, 1] * self.ureg.m),
-            [1, 3] * self.ureg.m,
-        )
-
-    # @helpers.requires_array_function_protocol()
-    def test_linalg_norm(self):
-        q = np.array([[3, 5, 8], [4, 12, 15]]) * self.ureg.m
-        expected = [5, 13, 17] * self.ureg.m
-        helpers.assert_quantity_equal(pnp.linalg.norm(q, axis=0), expected)
-
-
-@pytest.mark.skip
-class TestBitTwiddlingUfuncs(TestUFuncs):
-    """Universal functions (ufuncs) >  Bittwiddling functions
-
-    http://docs.scipy.org/doc/numpy/reference/ufuncs.html#bittwiddlingfunctions
-
-    bitwise_and(x1, x2[, out])         Compute the bitwise AND of two arrays elementwise.
-    bitwise_or(x1, x2[, out])  Compute the bitwise OR of two arrays elementwise.
-    bitwise_xor(x1, x2[, out])         Compute the bitwise XOR of two arrays elementwise.
-    invert(x[, out])   Compute bitwise inversion, or bitwise NOT, elementwise.
-    left_shift(x1, x2[, out])  Shift the bits of an integer to the left.
-    right_shift(x1, x2[, out])         Shift the bits of an integer to the right.
-
-    Parameters
-    ----------
-
-    Returns
-    -------
-
-    """
-
-    @property
-    def qless(self):
-        return pnp.asarray([1, 2, 3, 4], dtype=pnp.uint8) * self.ureg.dimensionless
-
-    @property
-    def qs(self):
-        return 8 * self.ureg.J
-
-    @property
-    def q1(self):
-        return pnp.asarray([1, 2, 3, 4], dtype=pnp.uint8) * self.ureg.J
-
-    @property
-    def q2(self):
-        return 2 * self.q1
-
-    @property
-    def qm(self):
-        return pnp.asarray([1, 2, 3, 4], dtype=pnp.uint8) * self.ureg.m
-
-    def test_bitwise_and(self):
-        self._test2(pnp.bitwise_and, self.q1, (self.q2, self.qs), (self.qm,), "same")
-
-    def test_bitwise_or(self):
-        self._test2(
-            pnp.bitwise_or, self.q1, (self.q1, self.q2, self.qs), (self.qm,), "same"
-        )
-
-    def test_bitwise_xor(self):
-        self._test2(
-            pnp.bitwise_xor, self.q1, (self.q1, self.q2, self.qs), (self.qm,), "same"
-        )
-
-    def test_invert(self):
-        self._test1(pnp.invert, (self.q1, self.q2, self.qs), (), "same")
-
-    def test_left_shift(self):
-        self._test2(
-            pnp.left_shift, self.q1, (self.qless, 2), (self.q1, self.q2, self.qs), "same"
-        )
-
-    def test_right_shift(self):
-        self._test2(
-            pnp.right_shift,
-            self.q1,
-            (self.qless, 2),
-            (self.q1, self.q2, self.qs),
-            "same",
-        )

From 1ad9ca97ee86331347b1109ff31a64e73f84fe2a Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Sat, 4 Jan 2025 21:55:21 +0000
Subject: [PATCH 03/49] style: pre-commit fixes

---
 src/pint_array/__init__.py |  5 ++---
 tests/test_array.py        | 24 +++++++++++++-----------
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index dcbdc9b..56b7a72 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -623,18 +623,17 @@ def fun(x, /, *args, func_str=func_str, **kwargs):
             return ArrayUnitQuantity(magnitude, x.units)
 
         setattr(mod, func_str, fun)
-    
+
     for func_str in ["sqrt"]:
 
         def fun(x, /, *args, func_str=func_str, **kwargs):
             x = asarray(x)
             magnitude = xp.asarray(x.magnitude, copy=True)
             magnitude = getattr(xp, func_str)(magnitude, *args, **kwargs)
-            return ArrayUnitQuantity(magnitude, x.units ** 0.5)
+            return ArrayUnitQuantity(magnitude, x.units**0.5)
 
         setattr(mod, func_str, fun)
 
-
     elementwise_two_arrays = [
         "add",
         "atan2",
diff --git a/tests/test_array.py b/tests/test_array.py
index 4f0532b..e9fca71 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -3,21 +3,22 @@
 import copy
 import operator as op
 import pickle
-import warnings
 
+import numpy as np
 import pytest
+from pint import DimensionalityError, OffsetUnitCalculusError
 
-from pint import DimensionalityError, OffsetUnitCalculusError, UnitStrippedWarning
 # from pint.compat import np
 from pint.testsuite import helpers
-from pint.testsuite.test_umath import TestUFuncs
 
-import pint_array; 
-import numpy as np; 
-pnp = pint_array.pint_namespace(np); 
-from pint import UnitRegistry; 
+import pint_array
+
+pnp = pint_array.pint_namespace(np)
+from pint import UnitRegistry
+
 ureg = UnitRegistry()
 
+
 # @helpers.requires_numpy
 class TestNumpyMethods:
     @classmethod
@@ -98,7 +99,7 @@ def test_flatten(self):
         helpers.assert_quantity_equal(self.q.flatten(), [1, 2, 3, 4] * self.ureg.m)
 
     def test_flat(self):
-        for q, v in zip(self.q.flat, [1, 2, 3, 4]):
+        for q, v in zip(self.q.flat, [1, 2, 3, 4], strict=False):
             assert q == v * self.ureg.m
 
     def test_reshape(self):
@@ -212,7 +213,9 @@ def test_prod_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.prod(self.q, axis=axis), [3, 8] * self.ureg.m**2
         )
-        helpers.assert_quantity_equal(pnp.prod(self.q, where=where), 12 * self.ureg.m**3)
+        helpers.assert_quantity_equal(
+            pnp.prod(self.q, where=where), 12 * self.ureg.m**3
+        )
 
         with pytest.raises(DimensionalityError):
             pnp.prod(self.q, axis=axis, where=where)
@@ -300,7 +303,6 @@ def test_exponentiation_array_exp_2(self):
 
 
 class TestNumpyUnclassified(TestNumpyMethods):
-
     def test_repeat(self):
         helpers.assert_quantity_equal(
             pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
@@ -514,7 +516,7 @@ def test_equal(self):
         self.assertNDArrayEqual(v == w, false)
         self.assertNDArrayEqual(v == w.to("mm"), false)
         self.assertNDArrayEqual(u == v, false)
-    
+
     def test_dtype(self):
         u = self.Q_(pnp.arange(12, dtype="uint32"))
 

From 984a3c9b0bce624b85a9102f12f783d1d5894e4a Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 5 Jan 2025 15:41:46 +0000
Subject: [PATCH 04/49] tests

---
 src/pint_array/__init__.py |  1 +
 tests/test_array.py        | 79 +++++++++++++++++++-------------------
 2 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index dcbdc9b..e37ca13 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -720,6 +720,7 @@ def linalg_fun(x1, x2, /, **kwargs):
         setattr(mod, name, get_linalg_fun(name))
 
     def matrix_transpose(x):
+        x = asarray(x)
         return x.mT
 
     mod.matrix_transpose = matrix_transpose
diff --git a/tests/test_array.py b/tests/test_array.py
index 4f0532b..5d23986 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -18,7 +18,6 @@
 from pint import UnitRegistry; 
 ureg = UnitRegistry()
 
-# @helpers.requires_numpy
 class TestNumpyMethods:
     @classmethod
     def setup_class(cls):
@@ -62,21 +61,22 @@ def assertNDArrayEqual(self, actual, desired):
 class TestNumpyArrayCreation(TestNumpyMethods):
     # https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html
 
-    # @helpers.requires_array_function_protocol()
+    @pytest.mark.xfail(reason="Scalar arguement issue ")
     def test_ones_like(self):
         self.assertNDArrayEqual(pnp.ones_like(self.q), np.array([[1, 1], [1, 1]]))
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_zeros_like(self):
         self.assertNDArrayEqual(pnp.zeros_like(self.q), np.array([[0, 0], [0, 0]]))
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_empty_like(self):
         ret = pnp.empty_like(self.q)
         assert ret.shape == (2, 2)
-        assert isinstance(ret, np.ndarray)
+        assert isinstance(ret.magnitude, np.ndarray)
 
-    # @helpers.requires_array_function_protocol()
+    
+    @pytest.mark.xfail(reason="Scalar arguement issue ")
     def test_full_like(self):
         helpers.assert_quantity_equal(
             pnp.full_like(self.q, self.Q_(0, self.ureg.degC)),
@@ -108,19 +108,19 @@ def test_reshape(self):
 
     # Transpose-like operations
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_moveaxis(self):
         helpers.assert_quantity_equal(
             pnp.moveaxis(self.q, 1, 0), np.array([[1, 2], [3, 4]]).T * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_transpose(self):
         helpers.assert_quantity_equal(
             pnp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_flip_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
@@ -128,20 +128,20 @@ def test_flip_numpy_func(self):
 
     # Changing number of dimensions
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_broadcast_to(self):
         helpers.assert_quantity_equal(
             pnp.broadcast_to(self.q[:, 1], (2, 2)),
             np.array([[2, 4], [2, 4]]) * self.ureg.m,
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_expand_dims(self):
         helpers.assert_quantity_equal(
             pnp.expand_dims(self.q, 0), np.array([[[1, 2], [3, 4]]]) * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_squeeze(self):
         helpers.assert_quantity_equal(pnp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
@@ -150,7 +150,7 @@ def test_squeeze(self):
 
     # Changing number of dimensions
     # Joining arrays
-    # @helpers.requires_array_function_protocol()
+    
     def test_concat_stack(self, subtests):
         for func in (pnp.concat, pnp.stack):
             with subtests.test(func=func):
@@ -203,7 +203,7 @@ def test_roll(self):
 class TestNumpyMathematicalFunctions(TestNumpyMethods):
     # https://www.numpy.org/devdocs/reference/routines.math.html
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_prod_numpy_func(self):
         axis = 0
         where = [[True, False], [True, True]]
@@ -224,7 +224,7 @@ def test_prod_numpy_func(self):
             pnp.prod(self.q, axis=axis, where=[True, False]), [3, 1] * self.ureg.m**2
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_sum_numpy_func(self):
         helpers.assert_quantity_equal(pnp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
         with pytest.raises(OffsetUnitCalculusError):
@@ -280,7 +280,6 @@ def test_sqrt(self):
         helpers.assert_quantity_equal(pnp.sqrt(q), self.Q_(10, "m"))
 
     @pytest.mark.xfail
-    # @helpers.requires_numpy
     def test_exponentiation_array_exp_2(self):
         arr = np.array(range(3), dtype=float)
         # q = self.Q_(copy.copy(arr), None)
@@ -306,34 +305,34 @@ def test_repeat(self):
             pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_sort_numpy_func(self):
         q = [4, 5, 2, 3, 1, 6] * self.ureg.m
         helpers.assert_quantity_equal(pnp.sort(q), [1, 2, 3, 4, 5, 6] * self.ureg.m)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_argsort_numpy_func(self):
         self.assertNDArrayEqual(pnp.argsort(self.q, axis=0), np.array([[0, 0], [1, 1]]))
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_searchsorted_numpy_func(self):
         """Test searchsorted as numpy function."""
         q = self.q.flatten()
         self.assertNDArrayEqual(pnp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_nonzero_numpy_func(self):
         q = [1, 0, 5, 6, 0, 9] * self.ureg.m
         self.assertNDArrayEqual(pnp.nonzero(q)[0], [0, 2, 3, 5])
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_any_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert pnp.any(q)
         with pytest.raises(ValueError):
             pnp.any(self.q_temperature)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_all_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert not pnp.all(q)
@@ -343,18 +342,18 @@ def test_all_numpy_func(self):
     def test_max_numpy_func(self):
         assert pnp.max(self.q) == 4 * self.ureg.m
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_max_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.max(self.q, axis=1), [2, 4] * self.ureg.m)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_max_with_initial_arg(self):
         helpers.assert_quantity_equal(
             pnp.max(self.q[..., None], axis=2, initial=3 * self.ureg.m),
             [[3, 3], [3, 4]] * self.ureg.m,
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_argmax_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmax(self.q, axis=0), np.array([1, 1]))
 
@@ -363,22 +362,22 @@ def test_maximum(self):
             pnp.maximum(self.q, self.Q_([0, 5], "m")), self.Q_([[1, 5], [3, 5]], "m")
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_min_numpy_func(self):
         assert pnp.min(self.q) == 1 * self.ureg.m
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_min_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.min(self.q, axis=1), [1, 3] * self.ureg.m)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_min_with_initial_arg(self):
         helpers.assert_quantity_equal(
             pnp.min(self.q[..., None], axis=2, initial=3 * self.ureg.m),
             [[1, 2], [3, 3]] * self.ureg.m,
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_argmin_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmin(self.q, axis=0), np.array([0, 0]))
 
@@ -387,35 +386,35 @@ def test_minimum(self):
             pnp.minimum(self.q, self.Q_([0, 5], "m")), self.Q_([[0, 2], [0, 4]], "m")
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_clip_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_round_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_cumulative_sum(self):
         helpers.assert_quantity_equal(
             pnp.cumulative_sum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_mean_numpy_func(self):
         assert pnp.mean(self.q) == 2.5 * self.ureg.m
         assert pnp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_var_numpy_func(self):
         assert pnp.var(self.q) == 1.25 * self.ureg.m**2
         assert pnp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_std_numpy_func(self):
         helpers.assert_quantity_almost_equal(
             pnp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
@@ -520,15 +519,15 @@ def test_dtype(self):
 
         assert u.dtype == "uint32"
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_shape_numpy_func(self):
         assert pnp.asarray(self.q).shape == (2, 2)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_ndim_numpy_func(self):
         assert pnp.asarray(self.q).ndim == 2
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_meshgrid_numpy_func(self):
         x = [1, 2] * self.ureg.m
         y = [0, 50, 100] * self.ureg.mm
@@ -544,7 +543,7 @@ def test_comparisons(self):
             self.q < 2 * self.ureg.m, np.array([[True, False], [False, False]])
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_where(self):
         helpers.assert_quantity_equal(
             pnp.where(self.q >= 2 * self.ureg.m, self.q, 20 * self.ureg.m),
@@ -593,7 +592,7 @@ def test_where(self):
                 self.ureg.Quantity([-1, 0, 1], "degC"), [1, 2, 1] * self.ureg.s, pnp.nan
             )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_tile(self):
         helpers.assert_quantity_equal(
             pnp.tile(self.q, 2), np.array([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m

From 849825612d91bd73ea7be7017f876269fa983b1d Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Sun, 5 Jan 2025 15:43:00 +0000
Subject: [PATCH 05/49] style: pre-commit fixes

---
 tests/test_array.py | 38 ++------------------------------------
 1 file changed, 2 insertions(+), 36 deletions(-)

diff --git a/tests/test_array.py b/tests/test_array.py
index 61db7c6..3cf19b8 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -18,6 +18,7 @@
 
 ureg = UnitRegistry()
 
+
 class TestNumpyMethods:
     @classmethod
     def setup_class(cls):
@@ -65,17 +66,14 @@ class TestNumpyArrayCreation(TestNumpyMethods):
     def test_ones_like(self):
         self.assertNDArrayEqual(pnp.ones_like(self.q), np.array([[1, 1], [1, 1]]))
 
-    
     def test_zeros_like(self):
         self.assertNDArrayEqual(pnp.zeros_like(self.q), np.array([[0, 0], [0, 0]]))
 
-    
     def test_empty_like(self):
         ret = pnp.empty_like(self.q)
         assert ret.shape == (2, 2)
         assert isinstance(ret.magnitude, np.ndarray)
 
-    
     @pytest.mark.xfail(reason="Scalar arguement issue ")
     def test_full_like(self):
         helpers.assert_quantity_equal(
@@ -108,19 +106,16 @@ def test_reshape(self):
 
     # Transpose-like operations
 
-    
     def test_moveaxis(self):
         helpers.assert_quantity_equal(
             pnp.moveaxis(self.q, 1, 0), np.array([[1, 2], [3, 4]]).T * self.ureg.m
         )
 
-    
     def test_transpose(self):
         helpers.assert_quantity_equal(
             pnp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
         )
 
-    
     def test_flip_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
@@ -128,20 +123,17 @@ def test_flip_numpy_func(self):
 
     # Changing number of dimensions
 
-    
     def test_broadcast_to(self):
         helpers.assert_quantity_equal(
             pnp.broadcast_to(self.q[:, 1], (2, 2)),
             np.array([[2, 4], [2, 4]]) * self.ureg.m,
         )
 
-    
     def test_expand_dims(self):
         helpers.assert_quantity_equal(
             pnp.expand_dims(self.q, 0), np.array([[[1, 2], [3, 4]]]) * self.ureg.m
         )
 
-    
     def test_squeeze(self):
         helpers.assert_quantity_equal(pnp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
@@ -150,7 +142,7 @@ def test_squeeze(self):
 
     # Changing number of dimensions
     # Joining arrays
-    
+
     def test_concat_stack(self, subtests):
         for func in (pnp.concat, pnp.stack):
             with subtests.test(func=func):
@@ -203,7 +195,6 @@ def test_roll(self):
 class TestNumpyMathematicalFunctions(TestNumpyMethods):
     # https://www.numpy.org/devdocs/reference/routines.math.html
 
-    
     def test_prod_numpy_func(self):
         axis = 0
         where = [[True, False], [True, True]]
@@ -226,7 +217,6 @@ def test_prod_numpy_func(self):
             pnp.prod(self.q, axis=axis, where=[True, False]), [3, 1] * self.ureg.m**2
         )
 
-    
     def test_sum_numpy_func(self):
         helpers.assert_quantity_equal(pnp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
         with pytest.raises(OffsetUnitCalculusError):
@@ -306,34 +296,28 @@ def test_repeat(self):
             pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
         )
 
-    
     def test_sort_numpy_func(self):
         q = [4, 5, 2, 3, 1, 6] * self.ureg.m
         helpers.assert_quantity_equal(pnp.sort(q), [1, 2, 3, 4, 5, 6] * self.ureg.m)
 
-    
     def test_argsort_numpy_func(self):
         self.assertNDArrayEqual(pnp.argsort(self.q, axis=0), np.array([[0, 0], [1, 1]]))
 
-    
     def test_searchsorted_numpy_func(self):
         """Test searchsorted as numpy function."""
         q = self.q.flatten()
         self.assertNDArrayEqual(pnp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
 
-    
     def test_nonzero_numpy_func(self):
         q = [1, 0, 5, 6, 0, 9] * self.ureg.m
         self.assertNDArrayEqual(pnp.nonzero(q)[0], [0, 2, 3, 5])
 
-    
     def test_any_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert pnp.any(q)
         with pytest.raises(ValueError):
             pnp.any(self.q_temperature)
 
-    
     def test_all_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert not pnp.all(q)
@@ -343,18 +327,15 @@ def test_all_numpy_func(self):
     def test_max_numpy_func(self):
         assert pnp.max(self.q) == 4 * self.ureg.m
 
-    
     def test_max_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.max(self.q, axis=1), [2, 4] * self.ureg.m)
 
-    
     def test_max_with_initial_arg(self):
         helpers.assert_quantity_equal(
             pnp.max(self.q[..., None], axis=2, initial=3 * self.ureg.m),
             [[3, 3], [3, 4]] * self.ureg.m,
         )
 
-    
     def test_argmax_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmax(self.q, axis=0), np.array([1, 1]))
 
@@ -363,22 +344,18 @@ def test_maximum(self):
             pnp.maximum(self.q, self.Q_([0, 5], "m")), self.Q_([[1, 5], [3, 5]], "m")
         )
 
-    
     def test_min_numpy_func(self):
         assert pnp.min(self.q) == 1 * self.ureg.m
 
-    
     def test_min_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.min(self.q, axis=1), [1, 3] * self.ureg.m)
 
-    
     def test_min_with_initial_arg(self):
         helpers.assert_quantity_equal(
             pnp.min(self.q[..., None], axis=2, initial=3 * self.ureg.m),
             [[1, 2], [3, 3]] * self.ureg.m,
         )
 
-    
     def test_argmin_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmin(self.q, axis=0), np.array([0, 0]))
 
@@ -387,35 +364,29 @@ def test_minimum(self):
             pnp.minimum(self.q, self.Q_([0, 5], "m")), self.Q_([[0, 2], [0, 4]], "m")
         )
 
-    
     def test_clip_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
         )
 
-    
     def test_round_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
         )
 
-    
     def test_cumulative_sum(self):
         helpers.assert_quantity_equal(
             pnp.cumulative_sum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
         )
 
-    
     def test_mean_numpy_func(self):
         assert pnp.mean(self.q) == 2.5 * self.ureg.m
         assert pnp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
 
-    
     def test_var_numpy_func(self):
         assert pnp.var(self.q) == 1.25 * self.ureg.m**2
         assert pnp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
 
-    
     def test_std_numpy_func(self):
         helpers.assert_quantity_almost_equal(
             pnp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
@@ -520,15 +491,12 @@ def test_dtype(self):
 
         assert u.dtype == "uint32"
 
-    
     def test_shape_numpy_func(self):
         assert pnp.asarray(self.q).shape == (2, 2)
 
-    
     def test_ndim_numpy_func(self):
         assert pnp.asarray(self.q).ndim == 2
 
-    
     def test_meshgrid_numpy_func(self):
         x = [1, 2] * self.ureg.m
         y = [0, 50, 100] * self.ureg.mm
@@ -544,7 +512,6 @@ def test_comparisons(self):
             self.q < 2 * self.ureg.m, np.array([[True, False], [False, False]])
         )
 
-    
     def test_where(self):
         helpers.assert_quantity_equal(
             pnp.where(self.q >= 2 * self.ureg.m, self.q, 20 * self.ureg.m),
@@ -593,7 +560,6 @@ def test_where(self):
                 self.ureg.Quantity([-1, 0, 1], "degC"), [1, 2, 1] * self.ureg.s, pnp.nan
             )
 
-    
     def test_tile(self):
         helpers.assert_quantity_equal(
             pnp.tile(self.q, 2), np.array([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m

From 3d367ba9e0ccc2679b5bc7aef7993a71c0bbdc90 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 5 Jan 2025 16:55:28 +0000
Subject: [PATCH 06/49] remove parts not in spec

---
 src/pint_array/__init__.py |  1 +
 tests/test_array.py        | 46 +++++++++-----------------------------
 2 files changed, 11 insertions(+), 36 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 169a111..4172954 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -339,6 +339,7 @@ def manip_fun(x, *args, **kwargs):
                 args[0] = repeats.magnitude
 
             if func_str in arbitrary_num_arrays and not one_array:
+                args = [asarray(arg, units = x[0].units).magnitude for arg in args]
                 magnitude = xp_func(*magnitude, *args, **kwargs)
             else:
                 magnitude = xp_func(magnitude, *args, **kwargs)
diff --git a/tests/test_array.py b/tests/test_array.py
index 3cf19b8..3be6d5f 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -150,10 +150,10 @@ def test_concat_stack(self, subtests):
                     func([self.q] * 2), self.Q_(func([self.q.m] * 2), self.ureg.m)
                 )
                 # One or more of the args is a bare array full of zeros or NaNs
-                helpers.assert_quantity_equal(
-                    func([self.q_zero_or_nan.m, self.q]),
-                    self.Q_(func([self.q_zero_or_nan.m, self.q.m]), self.ureg.m),
-                )
+                # helpers.assert_quantity_equal(
+                #     func([self.q_zero_or_nan.m, self.q]),
+                #     self.Q_(func([self.q_zero_or_nan.m, self.q.m]), self.ureg.m),
+                # )
                 # One or more of the args is a bare array with at least one non-zero,
                 # non-NaN element
                 nz = self.q_zero_or_nan
@@ -174,14 +174,13 @@ def test_broadcast_arrays(self):
         x = self.Q_(np.array([[1, 2, 3]]), "m")
         y = self.Q_(np.array([[4], [5]]), "nm")
         result = pnp.broadcast_arrays(x, y)
-        expected = self.Q_(
-            [
-                [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]],
-                [[4e-09, 4e-09, 4e-09], [5e-09, 5e-09, 5e-09]],
-            ],
-            "m",
+        expected = (self.Q_(np.array([[1, 2, 3],
+                         [1, 2, 3]]),"m"),
+                    self.Q_(np.array([[4, 4, 4],
+                         [5, 5, 5]]),"nm")
         )
-        helpers.assert_quantity_equal(result, expected)
+        helpers.assert_quantity_equal(result[0], expected[0])
+        helpers.assert_quantity_equal(result[1], expected[1])
 
         result = pnp.broadcast_arrays(x, y, subok=True)
         helpers.assert_quantity_equal(result, expected)
@@ -203,19 +202,6 @@ def test_prod_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.prod(self.q, axis=axis), [3, 8] * self.ureg.m**2
         )
-        helpers.assert_quantity_equal(
-            pnp.prod(self.q, where=where), 12 * self.ureg.m**3
-        )
-
-        with pytest.raises(DimensionalityError):
-            pnp.prod(self.q, axis=axis, where=where)
-        helpers.assert_quantity_equal(
-            pnp.prod(self.q, axis=axis, where=[[True, False], [False, True]]),
-            [1, 4] * self.ureg.m,
-        )
-        helpers.assert_quantity_equal(
-            pnp.prod(self.q, axis=axis, where=[True, False]), [3, 1] * self.ureg.m**2
-        )
 
     def test_sum_numpy_func(self):
         helpers.assert_quantity_equal(pnp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
@@ -330,12 +316,6 @@ def test_max_numpy_func(self):
     def test_max_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.max(self.q, axis=1), [2, 4] * self.ureg.m)
 
-    def test_max_with_initial_arg(self):
-        helpers.assert_quantity_equal(
-            pnp.max(self.q[..., None], axis=2, initial=3 * self.ureg.m),
-            [[3, 3], [3, 4]] * self.ureg.m,
-        )
-
     def test_argmax_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmax(self.q, axis=0), np.array([1, 1]))
 
@@ -350,12 +330,6 @@ def test_min_numpy_func(self):
     def test_min_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.min(self.q, axis=1), [1, 3] * self.ureg.m)
 
-    def test_min_with_initial_arg(self):
-        helpers.assert_quantity_equal(
-            pnp.min(self.q[..., None], axis=2, initial=3 * self.ureg.m),
-            [[1, 2], [3, 3]] * self.ureg.m,
-        )
-
     def test_argmin_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmin(self.q, axis=0), np.array([0, 0]))
 

From ea2e1c85cd32ad62dde12858a053fb1a149d4733 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Sun, 5 Jan 2025 16:55:47 +0000
Subject: [PATCH 07/49] style: pre-commit fixes

---
 src/pint_array/__init__.py | 2 +-
 tests/test_array.py        | 7 +++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 4172954..773f04b 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -339,7 +339,7 @@ def manip_fun(x, *args, **kwargs):
                 args[0] = repeats.magnitude
 
             if func_str in arbitrary_num_arrays and not one_array:
-                args = [asarray(arg, units = x[0].units).magnitude for arg in args]
+                args = [asarray(arg, units=x[0].units).magnitude for arg in args]
                 magnitude = xp_func(*magnitude, *args, **kwargs)
             else:
                 magnitude = xp_func(magnitude, *args, **kwargs)
diff --git a/tests/test_array.py b/tests/test_array.py
index 3be6d5f..6bc4f5d 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -174,10 +174,9 @@ def test_broadcast_arrays(self):
         x = self.Q_(np.array([[1, 2, 3]]), "m")
         y = self.Q_(np.array([[4], [5]]), "nm")
         result = pnp.broadcast_arrays(x, y)
-        expected = (self.Q_(np.array([[1, 2, 3],
-                         [1, 2, 3]]),"m"),
-                    self.Q_(np.array([[4, 4, 4],
-                         [5, 5, 5]]),"nm")
+        expected = (
+            self.Q_(np.array([[1, 2, 3], [1, 2, 3]]), "m"),
+            self.Q_(np.array([[4, 4, 4], [5, 5, 5]]), "nm"),
         )
         helpers.assert_quantity_equal(result[0], expected[0])
         helpers.assert_quantity_equal(result[1], expected[1])

From 29fef7e230c96c41349daec41f0183fa94927ad6 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 5 Jan 2025 17:38:01 +0000
Subject: [PATCH 08/49] tets

---
 src/pint_array/__init__.py | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 773f04b..bb892ef 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -474,10 +474,23 @@ def searchsorted(x1, x2, /, *, side="left", sorter=None):
 
     # ignore units of condition, convert x2 to units of x1
     def where(condition, x1, x2, /):
+        if not getattr(condition, "_is_multiplicative", True):
+            raise ValueError(
+                "Invalid units of the condition: Boolean value of Quantity with offset unit is ambiguous."
+            )
+
         condition = asarray(condition)
-        x1 = asarray(x1)
-        x2 = asarray(x2)
+        if hasattr(x1, "units") and hasattr(x2, "units"):
+            x1 = asarray(x1)
+            x2 = asarray(x2)
+        elif hasattr(x1, "units"):
+            x1 = asarray(x1)
+            x2 = asarray(x2, units=x1.units)
+        elif hasattr(x2, "units"):
+            x1 = asarray(x1, units=x2.units)
+            x2 = asarray(x2)
         units = x1.units
+        print(x2.m_as(units))
         magnitude = xp.where(condition.magnitude, x1.magnitude, x2.m_as(units))
         return ArrayUnitQuantity(magnitude, units)
 

From 32b8bd2c91bb8f4d74d83df25aa1950858fd3447 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 5 Jan 2025 23:29:03 +0000
Subject: [PATCH 09/49] implementations

---
 src/pint_array/__init__.py | 39 +++++++++++++++++++++++++++++++++++---
 tests/test_array.py        | 10 ----------
 2 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index bb892ef..06d5bf9 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -17,6 +17,7 @@
 from array_api_compat import size
 from pint import Quantity
 from pint.facets.plain import MagnitudeT, PlainQuantity
+from pint import DimensionalityError, OffsetUnitCalculusError
 
 __version__ = "0.0.1.dev0"
 __all__ = ["__version__", "pint_namespace"]
@@ -352,7 +353,7 @@ def manip_fun(x, *args, **kwargs):
 
         return manip_fun
 
-    creation_manip_functions = ["tril", "triu", "meshgrid"]
+    creation_manip_functions = ["tril", "triu"]
     manip_names = [
         "broadcast_arrays",
         "broadcast_to",
@@ -372,6 +373,19 @@ def manip_fun(x, *args, **kwargs):
     for name in manip_names + creation_manip_functions:
         setattr(mod, name, get_manip_fun(name))
 
+    def _meshgrid(*xi, **kwargs):
+        # Simply need to map input units to onto list of outputs
+        input_units = (x.units for x in xi)
+        res = xp.meshgrid(*(x.magnitude for x in xi), **kwargs)
+        return [out * unit for out, unit in zip(res, input_units)]
+    mod.meshgrid = _meshgrid
+    
+    def _broadcast_arrays(*arrays):
+        arrays = [asarray(array) for array in arrays]
+        res = xp.broadcast_arrays(*[array.magnitude for array in arrays])
+        return [ArrayUnitQuantity(magnitude, array.units) for magnitude, array in zip(res, arrays)]
+    mod.broadcast_arrays = _broadcast_arrays
+
     ## Data Type Functions and Data Types ##
     dtype_fun_names = ["can_cast", "finfo", "iinfo", "result_type"]
     for func_str in dtype_fun_names:
@@ -671,9 +685,7 @@ def fun(x, /, *args, func_str=func_str, **kwargs):
         "logical_xor",
         "maximum",
         "minimum",
-        "multiply",
         "not_equal",
-        "pow",
         "remainder",
         "subtract",
     ]
@@ -708,6 +720,27 @@ def multiply(x1, x2, /, *args, **kwargs):
 
     mod.multiply = multiply
 
+
+    def pow(x1, x2, /, *args, **kwargs):
+        x1 = asarray(x1)
+        x2 = asarray(x2)
+
+        if not x2.units.dimensionless:
+            raise DimensionalityError(x2.units, "dimensionless")
+        if x2.ndim > 0 and not xp.all(x2.magnitude == x2[0].magnitude):
+            raise DimensionalityError(
+                        x2.units,
+                        "dimensionless",
+                        extra_msg="The exponent must be a scalar or an array of all the same value.",
+                    )
+
+        units = x1.units ** x2.magnitude
+
+        magnitude = xp.pow(x1.magnitude, x2.magnitude, *args, **kwargs)
+        return ArrayUnitQuantity(magnitude, units)
+
+    mod.pow = pow
+
     ## Indexing Functions
     def take(x, indices, /, **kwargs):
         magnitude = xp.take(x.magnitude, indices.magnitude, **kwargs)
diff --git a/tests/test_array.py b/tests/test_array.py
index 6bc4f5d..1992adb 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -178,10 +178,6 @@ def test_broadcast_arrays(self):
             self.Q_(np.array([[1, 2, 3], [1, 2, 3]]), "m"),
             self.Q_(np.array([[4, 4, 4], [5, 5, 5]]), "nm"),
         )
-        helpers.assert_quantity_equal(result[0], expected[0])
-        helpers.assert_quantity_equal(result[1], expected[1])
-
-        result = pnp.broadcast_arrays(x, y, subok=True)
         helpers.assert_quantity_equal(result, expected)
 
     def test_roll(self):
@@ -235,7 +231,6 @@ def test_power(self):
             with pytest.raises(DimensionalityError):
                 op_(2.0, q_cp)
             arr_cp = copy.copy(arr)
-            arr_cp = copy.copy(arr)
             q_cp = copy.copy(q)
             with pytest.raises(DimensionalityError):
                 op_(q_cp, arr_cp)
@@ -368,11 +363,6 @@ def test_std_numpy_func(self):
             pnp.std(self.q_temperature), 1.11803 * self.ureg.delta_degC, rtol=1e-5
         )
 
-    def test_cumprod(self):
-        with pytest.raises(DimensionalityError):
-            self.q.cumprod()
-        helpers.assert_quantity_equal((self.q / self.ureg.m).cumprod(), [1, 2, 6, 24])
-
     def test_conj(self):
         helpers.assert_quantity_equal((self.q * (1 + 1j)).conj(), self.q * (1 - 1j))
         helpers.assert_quantity_equal(

From 3ce421440c59c45b2a9837bd2758c5206a8ef645 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Sun, 5 Jan 2025 23:29:13 +0000
Subject: [PATCH 10/49] style: pre-commit fixes

---
 src/pint_array/__init__.py | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 06d5bf9..c6f4fcb 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -15,9 +15,8 @@
 from typing import Generic
 
 from array_api_compat import size
-from pint import Quantity
+from pint import DimensionalityError, OffsetUnitCalculusError, Quantity
 from pint.facets.plain import MagnitudeT, PlainQuantity
-from pint import DimensionalityError, OffsetUnitCalculusError
 
 __version__ = "0.0.1.dev0"
 __all__ = ["__version__", "pint_namespace"]
@@ -377,13 +376,18 @@ def _meshgrid(*xi, **kwargs):
         # Simply need to map input units to onto list of outputs
         input_units = (x.units for x in xi)
         res = xp.meshgrid(*(x.magnitude for x in xi), **kwargs)
-        return [out * unit for out, unit in zip(res, input_units)]
+        return [out * unit for out, unit in zip(res, input_units, strict=False)]
+
     mod.meshgrid = _meshgrid
-    
+
     def _broadcast_arrays(*arrays):
         arrays = [asarray(array) for array in arrays]
         res = xp.broadcast_arrays(*[array.magnitude for array in arrays])
-        return [ArrayUnitQuantity(magnitude, array.units) for magnitude, array in zip(res, arrays)]
+        return [
+            ArrayUnitQuantity(magnitude, array.units)
+            for magnitude, array in zip(res, arrays, strict=False)
+        ]
+
     mod.broadcast_arrays = _broadcast_arrays
 
     ## Data Type Functions and Data Types ##
@@ -720,7 +724,6 @@ def multiply(x1, x2, /, *args, **kwargs):
 
     mod.multiply = multiply
 
-
     def pow(x1, x2, /, *args, **kwargs):
         x1 = asarray(x1)
         x2 = asarray(x2)
@@ -729,12 +732,12 @@ def pow(x1, x2, /, *args, **kwargs):
             raise DimensionalityError(x2.units, "dimensionless")
         if x2.ndim > 0 and not xp.all(x2.magnitude == x2[0].magnitude):
             raise DimensionalityError(
-                        x2.units,
-                        "dimensionless",
-                        extra_msg="The exponent must be a scalar or an array of all the same value.",
-                    )
+                x2.units,
+                "dimensionless",
+                extra_msg="The exponent must be a scalar or an array of all the same value.",
+            )
 
-        units = x1.units ** x2.magnitude
+        units = x1.units**x2.magnitude
 
         magnitude = xp.pow(x1.magnitude, x2.magnitude, *args, **kwargs)
         return ArrayUnitQuantity(magnitude, units)

From ba95c6c9d9f9ea9e0d6c5f4e1ec3defa4744724e Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 5 Jan 2025 23:32:06 +0000
Subject: [PATCH 11/49] dependency

---
 pyproject.toml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/pyproject.toml b/pyproject.toml
index ae4be4b..91de1ce 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -40,6 +40,7 @@ ipython = "ipython"
 
 [tool.pixi.feature.tests.dependencies]
 pytest = "*"
+pytest-subtests = "*"
 
 [tool.pixi.feature.tests.tasks]
 tests = "pytest"

From e39e23e7a02ed6c49ec812217748bb8a1166168a Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Mon, 6 Jan 2025 11:57:21 +0000
Subject: [PATCH 12/49] update lockfile

---
 pixi.lock | 119 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 75 insertions(+), 44 deletions(-)

diff --git a/pixi.lock b/pixi.lock
index ab1b665..96579da 100644
--- a/pixi.lock
+++ b/pixi.lock
@@ -42,7 +42,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ndindex-1.9.2-py310ha75aee5_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py310h5851e9f_0.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -50,6 +50,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python-3.10.16-he725a3c_1_cpython.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.10-5_cp310.conda
       - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8228510_1.conda
@@ -89,7 +90,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/ndindex-1.8-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py310ha1ddda0_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -97,6 +98,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.10.16-h870587a_1_cpython.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python_abi-3.10-5_cp310.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda
@@ -136,7 +138,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda
       - conda: https://prefix.dev/conda-forge/win-64/ndindex-1.9.2-py310ha8f682b_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.1-py310hb9d903e_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -144,6 +146,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/python-3.10.16-h37870fc_1_cpython.conda
       - conda: https://prefix.dev/conda-forge/win-64/python_abi-3.10-5_cp310.conda
       - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
@@ -201,7 +204,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ndindex-1.9.2-py313h536fd9c_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py313hb30382a_0.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -209,6 +212,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8228510_1.conda
@@ -250,7 +254,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/ndindex-1.8-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py313ha4a2180_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -258,6 +262,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda
@@ -299,7 +304,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda
       - conda: https://prefix.dev/conda-forge/win-64/ndindex-1.9.2-py313ha7868ed_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.1-py313hd65a2fa_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -307,6 +312,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
@@ -357,7 +363,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py313hb30382a_0.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_102_cp313.conda
@@ -391,7 +397,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.6-hdb05f8b_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py313ha4a2180_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_102_cp313.conda
@@ -425,7 +431,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda
       - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda
       - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.1-py313hd65a2fa_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_102_cp313.conda
@@ -467,7 +473,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
-      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.4-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/ipython-8.31.0-pyh707e725_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda
@@ -494,7 +500,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/ndindex-1.9.2-py313h536fd9c_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py313hb30382a_0.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda
@@ -511,6 +517,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/pyyaml-6.0.2-py313h536fd9c_1.conda
@@ -525,7 +532,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ukkonen-1.0.1-py313h33d0bda_5.conda
-      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.0-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2
       - pypi: .
@@ -548,7 +555,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
-      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.4-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/ipython-8.31.0-pyh707e725_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda
@@ -571,7 +578,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/ndindex-1.8-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py313ha4a2180_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda
@@ -588,6 +595,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/pyyaml-6.0.2-py313h20a7fcf_1.conda
@@ -602,7 +610,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/ukkonen-1.0.1-py313hf9c7212_5.conda
-      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.0-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2
       - pypi: .
@@ -625,7 +633,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
-      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.4-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda
       - conda: https://prefix.dev/conda-forge/noarch/ipython-8.31.0-pyh7428d3b_0.conda
@@ -648,7 +656,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/ndindex-1.9.2-py313ha7868ed_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.1-py313hd65a2fa_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda
@@ -663,6 +671,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/pyyaml-6.0.2-py313ha7868ed_1.conda
@@ -680,7 +689,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/ukkonen-1.0.1-py313h1ec8472_5.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-ha32ba9b_23.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.42.34433-he29a5d6_23.conda
-      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.0-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/vs2015_runtime-14.42.34433-hdffcdeb_23.conda
       - conda: https://prefix.dev/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2
@@ -713,6 +722,7 @@ packages:
   depends:
   - python >=3.9
   license: MIT
+  license_family: MIT
   purls:
   - pkg:pypi/array-api-compat?source=hash-mapping
   size: 38442
@@ -724,6 +734,7 @@ packages:
   - numpy
   - python >=3.9
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/array-api-strict?source=hash-mapping
   size: 53675
@@ -990,13 +1001,14 @@ packages:
   - setuptools
   - sortedcontainers >=2.1.0,<3.0.0
   license: MPL-2.0
+  license_family: MOZILLA
   purls:
   - pkg:pypi/hypothesis?source=hash-mapping
   size: 341990
   timestamp: 1735341651189
-- conda: https://prefix.dev/conda-forge/noarch/identify-2.6.4-pyhd8ed1ab_0.conda
-  sha256: 8acc3bfc7781ea1ddc8c013faff5106a0539e5671e31bee0d81011a1e2df20d8
-  md5: 5ec16e7ad9bab911ff0696940953f505
+- conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
+  sha256: e8ea11b8e39a98a9c34efb5c21c3fca718e31e1f41fd9ae5f6918b8eb402da59
+  md5: c1b0f663ff141265d1be1242259063f0
   depends:
   - python >=3.9
   - ukkonen
@@ -1004,8 +1016,8 @@ packages:
   license_family: MIT
   purls:
   - pkg:pypi/identify?source=hash-mapping
-  size: 78570
-  timestamp: 1735518781514
+  size: 78415
+  timestamp: 1736026672643
 - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
   sha256: 0ec8f4d02053cd03b0f3e63168316530949484f80e16f5e2fb199a1d117a89ca
   md5: 6837f3eff7dcea42ecd714ce1ac2b108
@@ -1796,6 +1808,7 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 7912254
@@ -1815,6 +1828,7 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 8478406
@@ -1834,6 +1848,7 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 5929029
@@ -1853,6 +1868,7 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 6513050
@@ -1872,6 +1888,7 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 6420026
@@ -1891,13 +1908,14 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 7147174
   timestamp: 1734905243335
-- conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda
-  sha256: 814b9dff1847b132c676ee6cc1a8cb2d427320779b93e1b6d76552275c128705
-  md5: 23cc74f77eb99315c0360ec3533147a9
+- conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
+  sha256: f62f6bca4a33ca5109b6d571b052a394d836956d21b25b7ffd03376abf7a481f
+  md5: 4ce6875f75469b2757a65e10a5d05e31
   depends:
   - __glibc >=2.17,<3.0.a0
   - ca-certificates
@@ -1905,22 +1923,22 @@ packages:
   license: Apache-2.0
   license_family: Apache
   purls: []
-  size: 2947466
-  timestamp: 1731377666602
-- conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda
-  sha256: bd1d58ced46e75efa3b842c61642fd12272c69e9fe4d7261078bc082153a1d53
-  md5: df307bbc703324722df0293c9ca2e418
+  size: 2937158
+  timestamp: 1736086387286
+- conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
+  sha256: 97772762abc70b3a537683ca9fc3ff3d6099eb64e4aba3b9c99e6fce48422d21
+  md5: 22f971393637480bda8c679f374d8861
   depends:
   - __osx >=11.0
   - ca-certificates
   license: Apache-2.0
   license_family: Apache
   purls: []
-  size: 2935176
-  timestamp: 1731377561525
-- conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda
-  sha256: e03045a0837e01ff5c75e9273a572553e7522290799807f918c917a9826a6484
-  md5: d0d805d9b5524a14efb51b3bff965e83
+  size: 2936415
+  timestamp: 1736086108693
+- conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
+  sha256: 519a06eaab7c878fbebb8cab98ea4a4465eafb1e9ed8c6ce67226068a80a92f0
+  md5: fb45308ba8bfe1abf1f4a27bad24a743
   depends:
   - ca-certificates
   - ucrt >=10.0.20348.0
@@ -1929,8 +1947,8 @@ packages:
   license: Apache-2.0
   license_family: Apache
   purls: []
-  size: 8491156
-  timestamp: 1731379715927
+  size: 8462960
+  timestamp: 1736088436984
 - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
   sha256: da157b19bcd398b9804c5c52fc000fcb8ab0525bdb9c70f95beaa0bb42f85af1
   md5: 3bfed7e6228ebf2f7b9eaa47f1b4e2aa
@@ -1995,7 +2013,7 @@ packages:
 - pypi: .
   name: pint-array
   version: 0.0.1.dev0
-  sha256: f755911bc8a921cbb2e3867f4638c8fc32d2f9090b17c405eefd0019e5c5335e
+  sha256: 24493191fd5707853309652b03e9a153a4d9ace5f7f1b9c9ccb73d824f68d514
   requires_python: '>=3.10'
   editable: true
 - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -2137,6 +2155,19 @@ packages:
   - pkg:pypi/pytest-metadata?source=hash-mapping
   size: 14532
   timestamp: 1734146281190
+- conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
+  sha256: 610b1f994b7409cc131b5ecc838e515bf2c89eddcddb0b18a85dc6823eddc3d9
+  md5: c94aae4e1b32cddb4e6a3dedeee8092b
+  depends:
+  - attrs >=19.2.0
+  - pytest >=7.4
+  - python >=3.9
+  license: MIT
+  license_family: MIT
+  purls:
+  - pkg:pypi/pytest-subtests?source=hash-mapping
+  size: 17983
+  timestamp: 1733872677650
 - conda: https://prefix.dev/conda-forge/linux-64/python-3.10.16-he725a3c_1_cpython.conda
   build_number: 1
   sha256: 3f90a2d5062a73cd2dd8a0027718aee1db93f7975b9cfe529e2c9aeec2db262e
@@ -2627,9 +2658,9 @@ packages:
   purls: []
   size: 754247
   timestamp: 1731710681163
-- conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.0-pyhd8ed1ab_0.conda
-  sha256: 82776f74e90a296b79415361faa6b10f360755c1fb8e6d59ca68509e6fe7e115
-  md5: 1d601bc1d28b5ce6d112b90f4b9b8ede
+- conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
+  sha256: c8bde4547ddbd21ea89e483a7c65d8a5e442c0db494b0b977e389b75b9d03d62
+  md5: 680b1c287b10cefc8bda0530b217229f
   depends:
   - distlib >=0.3.7,<1
   - filelock >=3.12.2,<4
@@ -2639,8 +2670,8 @@ packages:
   license_family: MIT
   purls:
   - pkg:pypi/virtualenv?source=hash-mapping
-  size: 3350255
-  timestamp: 1732609542072
+  size: 3350367
+  timestamp: 1735929107438
 - conda: https://prefix.dev/conda-forge/win-64/vs2015_runtime-14.42.34433-hdffcdeb_23.conda
   sha256: 568ce8151eaae256f1cef752fc78651ad7a86ff05153cc7a4740b52ae6536118
   md5: 5c176975ca2b8366abad3c97b3cd1e83

From 573558d1071a1e87403ceceb5e9ace69466df286 Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Mon, 6 Jan 2025 12:42:11 +0000
Subject: [PATCH 13/49] fix xp-tests

---
 pixi.lock                  |  2 +-
 pyproject.toml             |  2 +-
 src/pint_array/__init__.py | 43 ++++++++++++++++++++++++++------------
 tests/test_array.py        | 35 ++++++++++---------------------
 xp-tests-xfails.txt        |  2 ++
 5 files changed, 45 insertions(+), 39 deletions(-)

diff --git a/pixi.lock b/pixi.lock
index 96579da..523ac68 100644
--- a/pixi.lock
+++ b/pixi.lock
@@ -2013,7 +2013,7 @@ packages:
 - pypi: .
   name: pint-array
   version: 0.0.1.dev0
-  sha256: 24493191fd5707853309652b03e9a153a4d9ace5f7f1b9c9ccb73d824f68d514
+  sha256: 4a89db66462f8ea5ad75b3a9e4b4b623805532b36abed68b124c6e67a3022bfe
   requires_python: '>=3.10'
   editable: true
 - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
diff --git a/pyproject.toml b/pyproject.toml
index 91de1ce..e5e5a11 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -43,7 +43,7 @@ pytest = "*"
 pytest-subtests = "*"
 
 [tool.pixi.feature.tests.tasks]
-tests = "pytest"
+tests = "pytest tests"
 
 [tool.pixi.feature.xp-tests.dependencies]
 pytest = "*"
diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index c6f4fcb..8e03f93 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -15,7 +15,7 @@
 from typing import Generic
 
 from array_api_compat import size
-from pint import DimensionalityError, OffsetUnitCalculusError, Quantity
+from pint import DimensionalityError, Quantity
 from pint.facets.plain import MagnitudeT, PlainQuantity
 
 __version__ = "0.0.1.dev0"
@@ -493,9 +493,11 @@ def searchsorted(x1, x2, /, *, side="left", sorter=None):
     # ignore units of condition, convert x2 to units of x1
     def where(condition, x1, x2, /):
         if not getattr(condition, "_is_multiplicative", True):
-            raise ValueError(
-                "Invalid units of the condition: Boolean value of Quantity with offset unit is ambiguous."
+            msg = (
+                "Invalid units of the condition: "
+                "Boolean value of Quantity with offset unit is ambiguous."
             )
+            raise ValueError(msg)
 
         condition = asarray(condition)
         if hasattr(x1, "units") and hasattr(x2, "units"):
@@ -508,7 +510,6 @@ def where(condition, x1, x2, /):
             x1 = asarray(x1, units=x2.units)
             x2 = asarray(x2)
         units = x1.units
-        print(x2.m_as(units))
         magnitude = xp.where(condition.magnitude, x1.magnitude, x2.m_as(units))
         return ArrayUnitQuantity(magnitude, units)
 
@@ -730,16 +731,32 @@ def pow(x1, x2, /, *args, **kwargs):
 
         if not x2.units.dimensionless:
             raise DimensionalityError(x2.units, "dimensionless")
-        if x2.ndim > 0 and not xp.all(x2.magnitude == x2[0].magnitude):
-            raise DimensionalityError(
-                x2.units,
-                "dimensionless",
-                extra_msg="The exponent must be a scalar or an array of all the same value.",
-            )
-
-        units = x1.units**x2.magnitude
+        x2_magnitude = x2.magnitude
+        x2_magnitude_dtype = x2_magnitude.dtype
+        if xp.isdtype(x2_magnitude_dtype, "complex floating"):
+            as_scalar = complex
+        elif xp.isdtype(x2_magnitude_dtype, "real floating"):
+            as_scalar = float
+        elif xp.isdtype(x2_magnitude_dtype, "integral"):
+            as_scalar = int
+        else:
+            as_scalar = bool
+        if x2.ndim == 0:
+            units = x1.units ** as_scalar(x2_magnitude)
+        else:
+            x2_first_elem_magnitude = x2[(0,) * x2.ndim]
+            if not xp.all(x2_magnitude == x2_first_elem_magnitude):
+                extra_msg = (
+                    "The exponent must be a scalar or an array of all the same value."
+                )
+                raise DimensionalityError(
+                    x2.units,
+                    "dimensionless",
+                    extra_msg=extra_msg,
+                )
+            units = x1.units ** as_scalar(x2_first_elem_magnitude)
 
-        magnitude = xp.pow(x1.magnitude, x2.magnitude, *args, **kwargs)
+        magnitude = xp.pow(x1.magnitude, x2_magnitude, *args, **kwargs)
         return ArrayUnitQuantity(magnitude, units)
 
     mod.pow = pow
diff --git a/tests/test_array.py b/tests/test_array.py
index 1992adb..3bd2f58 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -6,20 +6,16 @@
 
 import numpy as np
 import pytest
-from pint import DimensionalityError, OffsetUnitCalculusError
-
-# from pint.compat import np
+from pint import DimensionalityError, OffsetUnitCalculusError, UnitRegistry
 from pint.testsuite import helpers
 
 import pint_array
 
 pnp = pint_array.pint_namespace(np)
-from pint import UnitRegistry
-
 ureg = UnitRegistry()
 
 
-class TestNumpyMethods:
+class TestNumPyMethods:
     @classmethod
     def setup_class(cls):
         from pint import _DEFAULT_REGISTRY
@@ -59,10 +55,10 @@ def assertNDArrayEqual(self, actual, desired):
         assert not isinstance(desired, self.Q_)
 
 
-class TestNumpyArrayCreation(TestNumpyMethods):
+class TestNumPyArrayCreation(TestNumPyMethods):
     # https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html
 
-    @pytest.mark.xfail(reason="Scalar arguement issue ")
+    @pytest.mark.xfail(reason="Scalar argument issue ")
     def test_ones_like(self):
         self.assertNDArrayEqual(pnp.ones_like(self.q), np.array([[1, 1], [1, 1]]))
 
@@ -74,7 +70,7 @@ def test_empty_like(self):
         assert ret.shape == (2, 2)
         assert isinstance(ret.magnitude, np.ndarray)
 
-    @pytest.mark.xfail(reason="Scalar arguement issue ")
+    @pytest.mark.xfail(reason="Scalar argument issue ")
     def test_full_like(self):
         helpers.assert_quantity_equal(
             pnp.full_like(self.q, self.Q_(0, self.ureg.degC)),
@@ -83,13 +79,7 @@ def test_full_like(self):
         self.assertNDArrayEqual(pnp.full_like(self.q, 2), np.array([[2, 2], [2, 2]]))
 
 
-class TestNumpyArrayManipulation(TestNumpyMethods):
-    # TODO
-    # https://www.numpy.org/devdocs/reference/routines.array-manipulation.html
-    # copyto
-    # broadcast
-    # asarray	asanyarray	asmatrix	asfarray	asfortranarray	ascontiguousarray	asarray_chkfinite	asscalar	require
-
+class TestNumPyArrayManipulation(TestNumPyMethods):
     # Changing array shape
 
     def test_flatten(self):
@@ -186,12 +176,11 @@ def test_roll(self):
         )
 
 
-class TestNumpyMathematicalFunctions(TestNumpyMethods):
+class TestNumPyMathematicalFunctions(TestNumPyMethods):
     # https://www.numpy.org/devdocs/reference/routines.math.html
 
     def test_prod_numpy_func(self):
         axis = 0
-        where = [[True, False], [True, True]]
 
         helpers.assert_quantity_equal(pnp.prod(self.q), 24 * self.ureg.m**4)
         helpers.assert_quantity_equal(
@@ -270,7 +259,7 @@ def test_exponentiation_array_exp_2(self):
             op.ipow(arr_cp, q_cp)
 
 
-class TestNumpyUnclassified(TestNumpyMethods):
+class TestNumPyUnclassified(TestNumPyMethods):
     def test_repeat(self):
         helpers.assert_quantity_equal(
             pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
@@ -295,13 +284,13 @@ def test_nonzero_numpy_func(self):
     def test_any_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert pnp.any(q)
-        with pytest.raises(ValueError):
+        with pytest.raises(ValueError, match="offset unit is ambiguous"):
             pnp.any(self.q_temperature)
 
     def test_all_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert not pnp.all(q)
-        with pytest.raises(ValueError):
+        with pytest.raises(ValueError, match="offset unit is ambiguous"):
             pnp.all(self.q_temperature)
 
     def test_max_numpy_func(self):
@@ -430,11 +419,10 @@ def test_pickle(self, subtests):
     def test_equal(self):
         x = self.q.magnitude
         u = self.Q_(pnp.ones(x.shape))
-        true = pnp.ones_like(x, dtype=np.bool_)
         false = pnp.zeros_like(x, dtype=np.bool_)
 
         helpers.assert_quantity_equal(u, u)
-        helpers.assert_quantity_equal(u == u, u.magnitude == u.magnitude)
+        helpers.assert_quantity_equal(u, u.magnitude)
         helpers.assert_quantity_equal(u == 1, u.magnitude == 1)
 
         v = self.Q_(pnp.zeros(x.shape), "m")
@@ -444,7 +432,6 @@ def test_equal(self):
             self.Q_(pnp.zeros_like(x), "m") == self.Q_(pnp.zeros_like(x), "s"),
             false,
         )
-        self.assertNDArrayEqual(v == v, true)
         self.assertNDArrayEqual(v == w, false)
         self.assertNDArrayEqual(v == w.to("mm"), false)
         self.assertNDArrayEqual(u == v, false)
diff --git a/xp-tests-xfails.txt b/xp-tests-xfails.txt
index cc659de..6369ae4 100644
--- a/xp-tests-xfails.txt
+++ b/xp-tests-xfails.txt
@@ -38,3 +38,5 @@ array_api_tests/test_has_names.py::test_has_names[linalg-vecdot]
 array_api_tests/test_has_names.py::test_has_names[linalg-vector_norm]
 # flaky on macos
 array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt
+# `pow` with array x2 is only defined when all elements of x2 are equal
+array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)]

From 5a8f6d44635ffca02085ba26190f947432daa986 Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Tue, 7 Jan 2025 23:35:51 +0000
Subject: [PATCH 14/49] np -> xp

---
 tests/test_array.py | 199 +++++++++++++++++++++++---------------------
 1 file changed, 102 insertions(+), 97 deletions(-)

diff --git a/tests/test_array.py b/tests/test_array.py
index 3bd2f58..b410d92 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -4,6 +4,7 @@
 import operator as op
 import pickle
 
+import array_api_strict as xp
 import numpy as np
 import pytest
 from pint import DimensionalityError, OffsetUnitCalculusError, UnitRegistry
@@ -11,7 +12,7 @@
 
 import pint_array
 
-pnp = pint_array.pint_namespace(np)
+pxp = pint_array.pint_namespace(xp)
 ureg = UnitRegistry()
 
 
@@ -34,15 +35,15 @@ def q(self):
 
     @property
     def q_scalar(self):
-        return np.array(5) * self.ureg.m
+        return pxp.asarray(5) * self.ureg.m
 
     @property
     def q_nan(self):
-        return [[1, 2], [3, pnp.nan]] * self.ureg.m
+        return [[1, 2], [3, pxp.nan]] * self.ureg.m
 
     @property
     def q_zero_or_nan(self):
-        return [[0, 0], [0, pnp.nan]] * self.ureg.m
+        return [[0, 0], [0, pxp.nan]] * self.ureg.m
 
     @property
     def q_temperature(self):
@@ -60,23 +61,23 @@ class TestNumPyArrayCreation(TestNumPyMethods):
 
     @pytest.mark.xfail(reason="Scalar argument issue ")
     def test_ones_like(self):
-        self.assertNDArrayEqual(pnp.ones_like(self.q), np.array([[1, 1], [1, 1]]))
+        self.assertNDArrayEqual(pxp.ones_like(self.q), pxp.asarray([[1, 1], [1, 1]]))
 
     def test_zeros_like(self):
-        self.assertNDArrayEqual(pnp.zeros_like(self.q), np.array([[0, 0], [0, 0]]))
+        self.assertNDArrayEqual(pxp.zeros_like(self.q), pxp.asarray([[0, 0], [0, 0]]))
 
     def test_empty_like(self):
-        ret = pnp.empty_like(self.q)
+        ret = pxp.empty_like(self.q)
         assert ret.shape == (2, 2)
-        assert isinstance(ret.magnitude, np.ndarray)
+        assert ret.magnitude.__array_namespace__() is xp
 
     @pytest.mark.xfail(reason="Scalar argument issue ")
     def test_full_like(self):
         helpers.assert_quantity_equal(
-            pnp.full_like(self.q, self.Q_(0, self.ureg.degC)),
+            pxp.full_like(self.q, self.Q_(0, self.ureg.degC)),
             self.Q_([[0, 0], [0, 0]], self.ureg.degC),
         )
-        self.assertNDArrayEqual(pnp.full_like(self.q, 2), np.array([[2, 2], [2, 2]]))
+        self.assertNDArrayEqual(pxp.full_like(self.q, 2), pxp.asarray([[2, 2], [2, 2]]))
 
 
 class TestNumPyArrayManipulation(TestNumPyMethods):
@@ -98,43 +99,43 @@ def test_reshape(self):
 
     def test_moveaxis(self):
         helpers.assert_quantity_equal(
-            pnp.moveaxis(self.q, 1, 0), np.array([[1, 2], [3, 4]]).T * self.ureg.m
+            pxp.moveaxis(self.q, 1, 0), pxp.asarray([[1, 2], [3, 4]]).T * self.ureg.m
         )
 
     def test_transpose(self):
         helpers.assert_quantity_equal(
-            pnp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
+            pxp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
         )
 
     def test_flip_numpy_func(self):
         helpers.assert_quantity_equal(
-            pnp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
+            pxp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
         )
 
     # Changing number of dimensions
 
     def test_broadcast_to(self):
         helpers.assert_quantity_equal(
-            pnp.broadcast_to(self.q[:, 1], (2, 2)),
-            np.array([[2, 4], [2, 4]]) * self.ureg.m,
+            pxp.broadcast_to(self.q[:, 1], (2, 2)),
+            pxp.asarray([[2, 4], [2, 4]]) * self.ureg.m,
         )
 
     def test_expand_dims(self):
         helpers.assert_quantity_equal(
-            pnp.expand_dims(self.q, 0), np.array([[[1, 2], [3, 4]]]) * self.ureg.m
+            pxp.expand_dims(self.q, 0), pxp.asarray([[[1, 2], [3, 4]]]) * self.ureg.m
         )
 
     def test_squeeze(self):
-        helpers.assert_quantity_equal(pnp.squeeze(self.q), self.q)
+        helpers.assert_quantity_equal(pxp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
-            pnp.squeeze(self.q.reshape([1, 4])), [1, 2, 3, 4] * self.ureg.m
+            pxp.squeeze(self.q.reshape([1, 4])), [1, 2, 3, 4] * self.ureg.m
         )
 
     # Changing number of dimensions
     # Joining arrays
 
     def test_concat_stack(self, subtests):
-        for func in (pnp.concat, pnp.stack):
+        for func in (pxp.concat, pxp.stack):
             with subtests.test(func=func):
                 helpers.assert_quantity_equal(
                     func([self.q] * 2), self.Q_(func([self.q.m] * 2), self.ureg.m)
@@ -152,8 +153,10 @@ def test_concat_stack(self, subtests):
                     func([nz.m, self.q])
 
     def test_astype(self):
-        actual = self.q.astype(pnp.float32)
-        expected = self.Q_(np.array([[1.0, 2.0], [3.0, 4.0]], dtype=pnp.float32), "m")
+        actual = self.q.astype(pxp.float32)
+        expected = self.Q_(
+            pxp.asarray([[1.0, 2.0], [3.0, 4.0]], dtype=pxp.float32), "m"
+        )
         helpers.assert_quantity_equal(actual, expected)
         assert actual.m.dtype == expected.m.dtype
 
@@ -161,18 +164,18 @@ def test_item(self):
         helpers.assert_quantity_equal(self.Q_([[0]], "m").item(), 0 * self.ureg.m)
 
     def test_broadcast_arrays(self):
-        x = self.Q_(np.array([[1, 2, 3]]), "m")
-        y = self.Q_(np.array([[4], [5]]), "nm")
-        result = pnp.broadcast_arrays(x, y)
+        x = self.Q_(pxp.asarray([[1, 2, 3]]), "m")
+        y = self.Q_(pxp.asarray([[4], [5]]), "nm")
+        result = pxp.broadcast_arrays(x, y)
         expected = (
-            self.Q_(np.array([[1, 2, 3], [1, 2, 3]]), "m"),
-            self.Q_(np.array([[4, 4, 4], [5, 5, 5]]), "nm"),
+            self.Q_(pxp.asarray([[1, 2, 3], [1, 2, 3]]), "m"),
+            self.Q_(pxp.asarray([[4, 4, 4], [5, 5, 5]]), "nm"),
         )
         helpers.assert_quantity_equal(result, expected)
 
     def test_roll(self):
         helpers.assert_quantity_equal(
-            pnp.roll(self.q, 1), [[4, 1], [2, 3]] * self.ureg.m
+            pxp.roll(self.q, 1), [[4, 1], [2, 3]] * self.ureg.m
         )
 
 
@@ -182,19 +185,19 @@ class TestNumPyMathematicalFunctions(TestNumPyMethods):
     def test_prod_numpy_func(self):
         axis = 0
 
-        helpers.assert_quantity_equal(pnp.prod(self.q), 24 * self.ureg.m**4)
+        helpers.assert_quantity_equal(pxp.prod(self.q), 24 * self.ureg.m**4)
         helpers.assert_quantity_equal(
-            pnp.prod(self.q, axis=axis), [3, 8] * self.ureg.m**2
+            pxp.prod(self.q, axis=axis), [3, 8] * self.ureg.m**2
         )
 
     def test_sum_numpy_func(self):
-        helpers.assert_quantity_equal(pnp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
+        helpers.assert_quantity_equal(pxp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
         with pytest.raises(OffsetUnitCalculusError):
-            pnp.sum(self.q_temperature)
+            pxp.sum(self.q_temperature)
 
     # Arithmetic operations
     def test_addition_with_scalar(self):
-        a = np.array([0, 1, 2])
+        a = pxp.asarray([0, 1, 2])
         b = 10.0 * self.ureg("gram/kilogram")
         helpers.assert_quantity_almost_equal(
             a + b, self.Q_([0.01, 1.01, 2.01], self.ureg.dimensionless)
@@ -204,7 +207,7 @@ def test_addition_with_scalar(self):
         )
 
     def test_addition_with_incompatible_scalar(self):
-        a = np.array([0, 1, 2])
+        a = pxp.asarray([0, 1, 2])
         b = 1.0 * self.ureg.m
         with pytest.raises(DimensionalityError):
             op.add(a, b)
@@ -212,10 +215,10 @@ def test_addition_with_incompatible_scalar(self):
             op.add(b, a)
 
     def test_power(self):
-        arr = np.array(range(3), dtype=float)
+        arr = pxp.asarray(range(3), dtype=float)
         q = self.Q_(arr, "meter")
 
-        for op_ in [pnp.pow]:
+        for op_ in [pxp.pow]:
             q_cp = copy.copy(q)
             with pytest.raises(DimensionalityError):
                 op_(2.0, q_cp)
@@ -229,20 +232,20 @@ def test_power(self):
                 op_(q_cp, q2_cp)
 
         helpers.assert_quantity_equal(
-            pnp.pow(self.q, self.Q_(2)), self.Q_([[1, 4], [9, 16]], "m**2")
+            pxp.pow(self.q, self.Q_(2)), self.Q_([[1, 4], [9, 16]], "m**2")
         )
         helpers.assert_quantity_equal(
             self.q ** self.Q_(2), self.Q_([[1, 4], [9, 16]], "m**2")
         )
-        self.assertNDArrayEqual(arr ** self.Q_(2), np.array([0, 1, 4]))
+        self.assertNDArrayEqual(arr ** self.Q_(2), pxp.asarray([0, 1, 4]))
 
     def test_sqrt(self):
         q = self.Q_(100, "m**2")
-        helpers.assert_quantity_equal(pnp.sqrt(q), self.Q_(10, "m"))
+        helpers.assert_quantity_equal(pxp.sqrt(q), self.Q_(10, "m"))
 
     @pytest.mark.xfail
     def test_exponentiation_array_exp_2(self):
-        arr = np.array(range(3), dtype=float)
+        arr = pxp.asarray(range(3), dtype=float)
         # q = self.Q_(copy.copy(arr), None)
         q = self.Q_(copy.copy(arr), "meter")
         arr_cp = copy.copy(arr)
@@ -262,94 +265,96 @@ def test_exponentiation_array_exp_2(self):
 class TestNumPyUnclassified(TestNumPyMethods):
     def test_repeat(self):
         helpers.assert_quantity_equal(
-            pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
+            pxp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
         )
 
     def test_sort_numpy_func(self):
         q = [4, 5, 2, 3, 1, 6] * self.ureg.m
-        helpers.assert_quantity_equal(pnp.sort(q), [1, 2, 3, 4, 5, 6] * self.ureg.m)
+        helpers.assert_quantity_equal(pxp.sort(q), [1, 2, 3, 4, 5, 6] * self.ureg.m)
 
     def test_argsort_numpy_func(self):
-        self.assertNDArrayEqual(pnp.argsort(self.q, axis=0), np.array([[0, 0], [1, 1]]))
+        self.assertNDArrayEqual(
+            pxp.argsort(self.q, axis=0), pxp.asarray([[0, 0], [1, 1]])
+        )
 
     def test_searchsorted_numpy_func(self):
         """Test searchsorted as numpy function."""
         q = self.q.flatten()
-        self.assertNDArrayEqual(pnp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
+        self.assertNDArrayEqual(pxp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
 
     def test_nonzero_numpy_func(self):
         q = [1, 0, 5, 6, 0, 9] * self.ureg.m
-        self.assertNDArrayEqual(pnp.nonzero(q)[0], [0, 2, 3, 5])
+        self.assertNDArrayEqual(pxp.nonzero(q)[0], [0, 2, 3, 5])
 
     def test_any_numpy_func(self):
         q = [0, 1] * self.ureg.m
-        assert pnp.any(q)
+        assert pxp.any(q)
         with pytest.raises(ValueError, match="offset unit is ambiguous"):
-            pnp.any(self.q_temperature)
+            pxp.any(self.q_temperature)
 
     def test_all_numpy_func(self):
         q = [0, 1] * self.ureg.m
-        assert not pnp.all(q)
+        assert not pxp.all(q)
         with pytest.raises(ValueError, match="offset unit is ambiguous"):
-            pnp.all(self.q_temperature)
+            pxp.all(self.q_temperature)
 
     def test_max_numpy_func(self):
-        assert pnp.max(self.q) == 4 * self.ureg.m
+        assert pxp.max(self.q) == 4 * self.ureg.m
 
     def test_max_with_axis_arg(self):
-        helpers.assert_quantity_equal(pnp.max(self.q, axis=1), [2, 4] * self.ureg.m)
+        helpers.assert_quantity_equal(pxp.max(self.q, axis=1), [2, 4] * self.ureg.m)
 
     def test_argmax_numpy_func(self):
-        self.assertNDArrayEqual(pnp.argmax(self.q, axis=0), np.array([1, 1]))
+        self.assertNDArrayEqual(pxp.argmax(self.q, axis=0), pxp.asarray([1, 1]))
 
     def test_maximum(self):
         helpers.assert_quantity_equal(
-            pnp.maximum(self.q, self.Q_([0, 5], "m")), self.Q_([[1, 5], [3, 5]], "m")
+            pxp.maximum(self.q, self.Q_([0, 5], "m")), self.Q_([[1, 5], [3, 5]], "m")
         )
 
     def test_min_numpy_func(self):
-        assert pnp.min(self.q) == 1 * self.ureg.m
+        assert pxp.min(self.q) == 1 * self.ureg.m
 
     def test_min_with_axis_arg(self):
-        helpers.assert_quantity_equal(pnp.min(self.q, axis=1), [1, 3] * self.ureg.m)
+        helpers.assert_quantity_equal(pxp.min(self.q, axis=1), [1, 3] * self.ureg.m)
 
     def test_argmin_numpy_func(self):
-        self.assertNDArrayEqual(pnp.argmin(self.q, axis=0), np.array([0, 0]))
+        self.assertNDArrayEqual(pxp.argmin(self.q, axis=0), pxp.asarray([0, 0]))
 
     def test_minimum(self):
         helpers.assert_quantity_equal(
-            pnp.minimum(self.q, self.Q_([0, 5], "m")), self.Q_([[0, 2], [0, 4]], "m")
+            pxp.minimum(self.q, self.Q_([0, 5], "m")), self.Q_([[0, 2], [0, 4]], "m")
         )
 
     def test_clip_numpy_func(self):
         helpers.assert_quantity_equal(
-            pnp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
+            pxp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
         )
 
     def test_round_numpy_func(self):
         helpers.assert_quantity_equal(
-            pnp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
+            pxp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
         )
 
     def test_cumulative_sum(self):
         helpers.assert_quantity_equal(
-            pnp.cumulative_sum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
+            pxp.cumulative_sum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
         )
 
     def test_mean_numpy_func(self):
-        assert pnp.mean(self.q) == 2.5 * self.ureg.m
-        assert pnp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
+        assert pxp.mean(self.q) == 2.5 * self.ureg.m
+        assert pxp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
 
     def test_var_numpy_func(self):
-        assert pnp.var(self.q) == 1.25 * self.ureg.m**2
-        assert pnp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
+        assert pxp.var(self.q) == 1.25 * self.ureg.m**2
+        assert pxp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
 
     def test_std_numpy_func(self):
         helpers.assert_quantity_almost_equal(
-            pnp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
+            pxp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
         )
         helpers.assert_quantity_almost_equal(
-            pnp.std(self.q_temperature), 1.11803 * self.ureg.delta_degC, rtol=1e-5
+            pxp.std(self.q_temperature), 1.11803 * self.ureg.delta_degC, rtol=1e-5
         )
 
     def test_conj(self):
@@ -372,7 +377,7 @@ def test_setitem(self):
         with pytest.raises(DimensionalityError):
             self.q[0] = 1
         with pytest.raises(DimensionalityError):
-            self.q[0] = np.ndarray([1, 2])
+            self.q[0] = pxp.asarray([1, 2])
         with pytest.raises(DimensionalityError):
             self.q[0] = 1 * self.ureg.J
 
@@ -391,9 +396,9 @@ def test_setitem(self):
         # check and see that dimensionless numbers work correctly
         q = [0, 1, 2, 3] * self.ureg.dimensionless
         q[0] = 1
-        helpers.assert_quantity_equal(q, pnp.asarray([1, 1, 2, 3]))
+        helpers.assert_quantity_equal(q, pxp.asarray([1, 1, 2, 3]))
         q[0] = self.ureg.m / self.ureg.mm
-        helpers.assert_quantity_equal(q, pnp.asarray([1000, 1, 2, 3]))
+        helpers.assert_quantity_equal(q, pxp.asarray([1000, 1, 2, 3]))
 
         q = [0.0, 1.0, 2.0, 3.0] * self.ureg.m / self.ureg.mm
         q[0] = 1.0
@@ -402,7 +407,7 @@ def test_setitem(self):
     def test_reversible_op(self):
         """ """
         x = self.q.magnitude
-        u = self.Q_(pnp.ones(x.shape))
+        u = self.Q_(pxp.ones(x.shape))
         helpers.assert_quantity_equal(x / self.q, u * x / self.q)
         helpers.assert_quantity_equal(x * self.q, u * x * self.q)
         helpers.assert_quantity_equal(x + u, u + x)
@@ -418,18 +423,18 @@ def test_pickle(self, subtests):
 
     def test_equal(self):
         x = self.q.magnitude
-        u = self.Q_(pnp.ones(x.shape))
-        false = pnp.zeros_like(x, dtype=np.bool_)
+        u = self.Q_(pxp.ones(x.shape))
+        false = pxp.zeros_like(x, dtype=pxp.bool)
 
         helpers.assert_quantity_equal(u, u)
         helpers.assert_quantity_equal(u, u.magnitude)
         helpers.assert_quantity_equal(u == 1, u.magnitude == 1)
 
-        v = self.Q_(pnp.zeros(x.shape), "m")
-        w = self.Q_(pnp.ones(x.shape), "m")
+        v = self.Q_(pxp.zeros(x.shape), "m")
+        w = self.Q_(pxp.ones(x.shape), "m")
         self.assertNDArrayEqual(v == 1, false)
         self.assertNDArrayEqual(
-            self.Q_(pnp.zeros_like(x), "m") == self.Q_(pnp.zeros_like(x), "s"),
+            self.Q_(pxp.zeros_like(x), "m") == self.Q_(pxp.zeros_like(x), "s"),
             false,
         )
         self.assertNDArrayEqual(v == w, false)
@@ -437,80 +442,80 @@ def test_equal(self):
         self.assertNDArrayEqual(u == v, false)
 
     def test_dtype(self):
-        u = self.Q_(pnp.arange(12, dtype="uint32"))
+        u = self.Q_(pxp.arange(12, dtype="uint32"))
 
         assert u.dtype == "uint32"
 
     def test_shape_numpy_func(self):
-        assert pnp.asarray(self.q).shape == (2, 2)
+        assert pxp.asarray(self.q).shape == (2, 2)
 
     def test_ndim_numpy_func(self):
-        assert pnp.asarray(self.q).ndim == 2
+        assert pxp.asarray(self.q).ndim == 2
 
     def test_meshgrid_numpy_func(self):
         x = [1, 2] * self.ureg.m
         y = [0, 50, 100] * self.ureg.mm
-        xx, yy = pnp.meshgrid(x, y)
+        xx, yy = pxp.meshgrid(x, y)
         helpers.assert_quantity_equal(xx, [[1, 2], [1, 2], [1, 2]] * self.ureg.m)
         helpers.assert_quantity_equal(yy, [[0, 0], [50, 50], [100, 100]] * self.ureg.mm)
 
     def test_comparisons(self):
         self.assertNDArrayEqual(
-            self.q > 2 * self.ureg.m, np.array([[False, False], [True, True]])
+            self.q > 2 * self.ureg.m, pxp.asarray([[False, False], [True, True]])
         )
         self.assertNDArrayEqual(
-            self.q < 2 * self.ureg.m, np.array([[True, False], [False, False]])
+            self.q < 2 * self.ureg.m, pxp.asarray([[True, False], [False, False]])
         )
 
     def test_where(self):
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 2 * self.ureg.m, self.q, 20 * self.ureg.m),
+            pxp.where(self.q >= 2 * self.ureg.m, self.q, 20 * self.ureg.m),
             [[20, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 2 * self.ureg.m, self.q, 0),
+            pxp.where(self.q >= 2 * self.ureg.m, self.q, 0),
             [[0, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 2 * self.ureg.m, self.q, pnp.nan),
-            [[pnp.nan, 2], [3, 4]] * self.ureg.m,
+            pxp.where(self.q >= 2 * self.ureg.m, self.q, pxp.nan),
+            [[pxp.nan, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 3 * self.ureg.m, 0, self.q),
+            pxp.where(self.q >= 3 * self.ureg.m, 0, self.q),
             [[1, 2], [0, 0]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 3 * self.ureg.m, pnp.nan, self.q),
-            [[1, 2], [pnp.nan, pnp.nan]] * self.ureg.m,
+            pxp.where(self.q >= 3 * self.ureg.m, pxp.nan, self.q),
+            [[1, 2], [pxp.nan, pxp.nan]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 2 * self.ureg.m, self.q, np.array(pnp.nan)),
-            [[pnp.nan, 2], [3, 4]] * self.ureg.m,
+            pxp.where(self.q >= 2 * self.ureg.m, self.q, pxp.asarray(pxp.nan)),
+            [[pxp.nan, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 3 * self.ureg.m, np.array(pnp.nan), self.q),
-            [[1, 2], [pnp.nan, pnp.nan]] * self.ureg.m,
+            pxp.where(self.q >= 3 * self.ureg.m, pxp.asarray(pxp.nan), self.q),
+            [[1, 2], [pxp.nan, pxp.nan]] * self.ureg.m,
         )
         with pytest.raises(DimensionalityError):
-            pnp.where(
+            pxp.where(
                 self.q < 2 * self.ureg.m,
                 self.q,
                 0 * self.ureg.J,
             )
 
         helpers.assert_quantity_equal(
-            pnp.where([-1, 0, 1] * self.ureg.m, [1, 2, 1] * self.ureg.s, pnp.nan),
-            [1, pnp.nan, 1] * self.ureg.s,
+            pxp.where([-1, 0, 1] * self.ureg.m, [1, 2, 1] * self.ureg.s, pxp.nan),
+            [1, pxp.nan, 1] * self.ureg.s,
         )
         with pytest.raises(
             ValueError,
             match=".*Boolean value of Quantity with offset unit is ambiguous",
         ):
-            pnp.where(
-                self.ureg.Quantity([-1, 0, 1], "degC"), [1, 2, 1] * self.ureg.s, pnp.nan
+            pxp.where(
+                self.ureg.Quantity([-1, 0, 1], "degC"), [1, 2, 1] * self.ureg.s, pxp.nan
             )
 
     def test_tile(self):
         helpers.assert_quantity_equal(
-            pnp.tile(self.q, 2), np.array([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m
+            pxp.tile(self.q, 2), pxp.asarray([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m
         )

From 9a49b08f15f644433e2b0a21c4674a233c871b5c Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Tue, 7 Jan 2025 23:37:27 +0000
Subject: [PATCH 15/49] remove pickle test

---
 tests/test_array.py | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/tests/test_array.py b/tests/test_array.py
index b410d92..db864c0 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -2,7 +2,6 @@
 
 import copy
 import operator as op
-import pickle
 
 import array_api_strict as xp
 import numpy as np
@@ -413,14 +412,6 @@ def test_reversible_op(self):
         helpers.assert_quantity_equal(x + u, u + x)
         helpers.assert_quantity_equal(x - u, -(u - x))
 
-    def test_pickle(self, subtests):
-        for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
-            with subtests.test(protocol):
-                q1 = [10, 20] * self.ureg.m
-                q2 = pickle.loads(pickle.dumps(q1, protocol))
-                self.assertNDArrayEqual(q1.magnitude, q2.magnitude)
-                assert q1.units == q2.units
-
     def test_equal(self):
         x = self.q.magnitude
         u = self.Q_(pxp.ones(x.shape))

From 135b2b9983eb258490133c9fbe0f5685642cf3f7 Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Tue, 7 Jan 2025 23:46:23 +0000
Subject: [PATCH 16/49] some tweaks

---
 src/pint_array/__init__.py |  2 ++
 tests/test_array.py        | 21 ++++++++++-----------
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 8e03f93..eb440db 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -946,4 +946,6 @@ def clip(x, /, min=None, max=None):
             with contextlib.suppress(AttributeError, TypeError):
                 mod_attr.__name__ = xp_attr.__name__
 
+    mod.ArrayUnitQuantity = ArrayUnitQuantity
+
     return mod
diff --git a/tests/test_array.py b/tests/test_array.py
index db864c0..2a37a2f 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -6,13 +6,12 @@
 import array_api_strict as xp
 import numpy as np
 import pytest
-from pint import DimensionalityError, OffsetUnitCalculusError, UnitRegistry
+from pint import DimensionalityError, OffsetUnitCalculusError
 from pint.testsuite import helpers
 
 import pint_array
 
 pxp = pint_array.pint_namespace(xp)
-ureg = UnitRegistry()
 
 
 class TestNumPyMethods:
@@ -21,7 +20,7 @@ def setup_class(cls):
         from pint import _DEFAULT_REGISTRY
 
         cls.ureg = _DEFAULT_REGISTRY
-        cls.Q_ = cls.ureg.Quantity
+        cls.Q_ = pxp.ArrayUnitQuantity
 
     @classmethod
     def teardown_class(cls):
@@ -30,23 +29,23 @@ def teardown_class(cls):
 
     @property
     def q(self):
-        return [[1, 2], [3, 4]] * self.ureg.m
+        return pxp.asarray([[1, 2], [3, 4]], units=self.ureg.m)
 
     @property
     def q_scalar(self):
-        return pxp.asarray(5) * self.ureg.m
+        return pxp.asarray(5, units=self.ureg.m)
 
     @property
     def q_nan(self):
-        return [[1, 2], [3, pxp.nan]] * self.ureg.m
+        return pxp.asarray([[1, 2], [3, pxp.nan]], units=self.ureg.m)
 
     @property
     def q_zero_or_nan(self):
-        return [[0, 0], [0, pxp.nan]] * self.ureg.m
+        return pxp.asarray([[0, 0], [0, pxp.nan]], units=self.ureg.m)
 
     @property
     def q_temperature(self):
-        return self.Q_([[1, 2], [3, 4]], self.ureg.degC)
+        return pxp.asarray([[1, 2], [3, 4]], self.ureg.degC)
 
     def assertNDArrayEqual(self, actual, desired):
         # Assert that the given arrays are equal, and are not Quantities
@@ -103,12 +102,12 @@ def test_moveaxis(self):
 
     def test_transpose(self):
         helpers.assert_quantity_equal(
-            pxp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
+            pxp.matrix_transpose(self.q), pxp.asarray([[1, 3], [2, 4]]) * self.ureg.m
         )
 
     def test_flip_numpy_func(self):
         helpers.assert_quantity_equal(
-            pxp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
+            pxp.flip(self.q, axis=0), pxp.asarray([[3, 4], [1, 2]]) * self.ureg.m
         )
 
     # Changing number of dimensions
@@ -127,7 +126,7 @@ def test_expand_dims(self):
     def test_squeeze(self):
         helpers.assert_quantity_equal(pxp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
-            pxp.squeeze(self.q.reshape([1, 4])), [1, 2, 3, 4] * self.ureg.m
+            pxp.squeeze(self.q.reshape([1, 4])), pxp.asarray([1, 2, 3, 4]) * self.ureg.m
         )
 
     # Changing number of dimensions

From bda9eba697f92e4bfe41a3f3813e589da7048eba Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sat, 11 Jan 2025 18:11:28 +0000
Subject: [PATCH 17/49] pass some tests

---
 src/pint_array/__init__.py |   2 +
 tests/test_array.py        | 114 ++++++++++++++++++++-----------------
 2 files changed, 63 insertions(+), 53 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index eb440db..609891e 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -115,6 +115,8 @@ def __mul__(self, other):
             else:
                 magnitude = self._call_super_method("__mul__", other)
                 units = self.units
+            if magnitude is NotImplemented:
+                return NotImplemented
             return ArrayUnitQuantity(magnitude, units)
 
         def __gt__(self, other):
diff --git a/tests/test_array.py b/tests/test_array.py
index 2a37a2f..dace652 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -45,7 +45,7 @@ def q_zero_or_nan(self):
 
     @property
     def q_temperature(self):
-        return pxp.asarray([[1, 2], [3, 4]], self.ureg.degC)
+        return pxp.asarray([[1, 2], [3, 4]], units = self.ureg.degC)
 
     def assertNDArrayEqual(self, actual, desired):
         # Assert that the given arrays are equal, and are not Quantities
@@ -61,6 +61,7 @@ class TestNumPyArrayCreation(TestNumPyMethods):
     def test_ones_like(self):
         self.assertNDArrayEqual(pxp.ones_like(self.q), pxp.asarray([[1, 1], [1, 1]]))
 
+    @pytest.mark.xfail(reason="should this be using NDArrayEqual?")
     def test_zeros_like(self):
         self.assertNDArrayEqual(pxp.zeros_like(self.q), pxp.asarray([[0, 0], [0, 0]]))
 
@@ -81,16 +82,9 @@ def test_full_like(self):
 class TestNumPyArrayManipulation(TestNumPyMethods):
     # Changing array shape
 
-    def test_flatten(self):
-        helpers.assert_quantity_equal(self.q.flatten(), [1, 2, 3, 4] * self.ureg.m)
-
-    def test_flat(self):
-        for q, v in zip(self.q.flat, [1, 2, 3, 4], strict=False):
-            assert q == v * self.ureg.m
-
     def test_reshape(self):
         helpers.assert_quantity_equal(
-            self.q.reshape([1, 4]), [[1, 2, 3, 4]] * self.ureg.m
+            pxp.reshape(self.q, [1, 4]), pxp.asarray([[1, 2, 3, 4]] ) * self.ureg.m
         )
 
     # Transpose-like operations
@@ -120,13 +114,13 @@ def test_broadcast_to(self):
 
     def test_expand_dims(self):
         helpers.assert_quantity_equal(
-            pxp.expand_dims(self.q, 0), pxp.asarray([[[1, 2], [3, 4]]]) * self.ureg.m
+            pxp.expand_dims(self.q, axis=0), pxp.asarray([[[1, 2], [3, 4]]]) * self.ureg.m
         )
 
     def test_squeeze(self):
-        helpers.assert_quantity_equal(pxp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
-            pxp.squeeze(self.q.reshape([1, 4])), pxp.asarray([1, 2, 3, 4]) * self.ureg.m
+            pxp.squeeze(pxp.asarray([[[0], [1], [2]]]) *self.ureg.m, axis=0),
+            pxp.asarray([0,1,2]) * self.ureg.m
         )
 
     # Changing number of dimensions
@@ -136,7 +130,7 @@ def test_concat_stack(self, subtests):
         for func in (pxp.concat, pxp.stack):
             with subtests.test(func=func):
                 helpers.assert_quantity_equal(
-                    func([self.q] * 2), self.Q_(func([self.q.m] * 2), self.ureg.m)
+                    func([self.q] * 2), pxp.asarray(func([self.q.m] * 2), units = "m")
                 )
                 # One or more of the args is a bare array full of zeros or NaNs
                 # helpers.assert_quantity_equal(
@@ -151,10 +145,9 @@ def test_concat_stack(self, subtests):
                     func([nz.m, self.q])
 
     def test_astype(self):
-        actual = self.q.astype(pxp.float32)
-        expected = self.Q_(
-            pxp.asarray([[1.0, 2.0], [3.0, 4.0]], dtype=pxp.float32), "m"
-        )
+        dtype=pxp.float32
+        actual = pxp.astype(self.q, dtype)
+        expected = pxp.asarray([[1.0, 2.0], [3.0, 4.0]], dtype=dtype, units = "m")
         helpers.assert_quantity_equal(actual, expected)
         assert actual.m.dtype == expected.m.dtype
 
@@ -162,12 +155,12 @@ def test_item(self):
         helpers.assert_quantity_equal(self.Q_([[0]], "m").item(), 0 * self.ureg.m)
 
     def test_broadcast_arrays(self):
-        x = self.Q_(pxp.asarray([[1, 2, 3]]), "m")
-        y = self.Q_(pxp.asarray([[4], [5]]), "nm")
+        x = pxp.asarray([[1, 2, 3]], units= "m")
+        y = pxp.asarray([[4], [5]], units= "nm")
         result = pxp.broadcast_arrays(x, y)
         expected = (
-            self.Q_(pxp.asarray([[1, 2, 3], [1, 2, 3]]), "m"),
-            self.Q_(pxp.asarray([[4, 4, 4], [5, 5, 5]]), "nm"),
+            pxp.asarray([[1, 2, 3], [1, 2, 3]], units= "m"),
+            pxp.asarray([[4, 4, 4], [5, 5, 5]], units= "nm")
         )
         helpers.assert_quantity_equal(result, expected)
 
@@ -195,13 +188,13 @@ def test_sum_numpy_func(self):
 
     # Arithmetic operations
     def test_addition_with_scalar(self):
-        a = pxp.asarray([0, 1, 2])
+        a = pxp.asarray([0, 1, 2], dtype = pxp.float32)
         b = 10.0 * self.ureg("gram/kilogram")
         helpers.assert_quantity_almost_equal(
-            a + b, self.Q_([0.01, 1.01, 2.01], self.ureg.dimensionless)
+            a + b, pxp.asarray([0.01, 1.01, 2.01], units = "")
         )
         helpers.assert_quantity_almost_equal(
-            b + a, self.Q_([0.01, 1.01, 2.01], self.ureg.dimensionless)
+            b + a, pxp.asarray([0.01, 1.01, 2.01], units = "")
         )
 
     def test_addition_with_incompatible_scalar(self):
@@ -213,7 +206,7 @@ def test_addition_with_incompatible_scalar(self):
             op.add(b, a)
 
     def test_power(self):
-        arr = pxp.asarray(range(3), dtype=float)
+        arr = pxp.asarray(range(3), dtype=pxp.float32)
         q = self.Q_(arr, "meter")
 
         for op_ in [pxp.pow]:
@@ -238,8 +231,8 @@ def test_power(self):
         self.assertNDArrayEqual(arr ** self.Q_(2), pxp.asarray([0, 1, 4]))
 
     def test_sqrt(self):
-        q = self.Q_(100, "m**2")
-        helpers.assert_quantity_equal(pxp.sqrt(q), self.Q_(10, "m"))
+        q = self.Q_(100.0, "m**2")
+        helpers.assert_quantity_equal(pxp.sqrt(q), self.Q_(10.0, "m"))
 
     @pytest.mark.xfail
     def test_exponentiation_array_exp_2(self):
@@ -326,12 +319,12 @@ def test_minimum(self):
 
     def test_clip_numpy_func(self):
         helpers.assert_quantity_equal(
-            pxp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
+            pxp.clip(pxp.asarray(self.q, dtype=pxp.float32), 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
         )
 
     def test_round_numpy_func(self):
         helpers.assert_quantity_equal(
-            pxp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
+            pxp.round(102.75 * self.ureg.m, ), 103 * self.ureg.m
         )
 
     def test_cumulative_sum(self):
@@ -340,19 +333,21 @@ def test_cumulative_sum(self):
         )
 
     def test_mean_numpy_func(self):
-        assert pxp.mean(self.q) == 2.5 * self.ureg.m
-        assert pxp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
+        assert pxp.mean(pxp.asarray(self.q, dtype=pxp.float32)) == 2.5 * self.ureg.m
+        assert pxp.mean(pxp.asarray(self.q_temperature, dtype=pxp.float32)) == self.Q_(2.5, self.ureg.degC)
 
     def test_var_numpy_func(self):
-        assert pxp.var(self.q) == 1.25 * self.ureg.m**2
-        assert pxp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
+        dtype=pxp.float32
+        assert pxp.var(pxp.asarray(self.q, dtype=dtype)) == 1.25 * self.ureg.m**2
+        assert pxp.var(pxp.asarray(self.q_temperature, dtype=dtype)) == 1.25 * self.ureg.delta_degC**2
 
     def test_std_numpy_func(self):
+        dtype=pxp.float32
         helpers.assert_quantity_almost_equal(
-            pxp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
+            pxp.std(pxp.asarray(self.q, dtype=dtype)), 1.11803 * self.ureg.m, rtol=1e-5
         )
         helpers.assert_quantity_almost_equal(
-            pxp.std(self.q_temperature), 1.11803 * self.ureg.delta_degC, rtol=1e-5
+            pxp.std(pxp.asarray(self.q_temperature, dtype=dtype)), 1.11803 * self.ureg.delta_degC, rtol=1e-5
         )
 
     def test_conj(self):
@@ -413,15 +408,15 @@ def test_reversible_op(self):
 
     def test_equal(self):
         x = self.q.magnitude
-        u = self.Q_(pxp.ones(x.shape))
+        u = pxp.ones(x.shape)
         false = pxp.zeros_like(x, dtype=pxp.bool)
 
         helpers.assert_quantity_equal(u, u)
         helpers.assert_quantity_equal(u, u.magnitude)
         helpers.assert_quantity_equal(u == 1, u.magnitude == 1)
 
-        v = self.Q_(pxp.zeros(x.shape), "m")
-        w = self.Q_(pxp.ones(x.shape), "m")
+        v = pxp.asarray((pxp.zeros(x.shape)), units = "m")
+        w = pxp.asarray((pxp.ones(x.shape)), units = "m")
         self.assertNDArrayEqual(v == 1, false)
         self.assertNDArrayEqual(
             self.Q_(pxp.zeros_like(x), "m") == self.Q_(pxp.zeros_like(x), "s"),
@@ -432,9 +427,10 @@ def test_equal(self):
         self.assertNDArrayEqual(u == v, false)
 
     def test_dtype(self):
-        u = self.Q_(pxp.arange(12, dtype="uint32"))
+        dtype=pxp.uint32
+        u = pxp.asarray([1, 2, 3], dtype=dtype)  * self.ureg.m
 
-        assert u.dtype == "uint32"
+        assert u.dtype == dtype
 
     def test_shape_numpy_func(self):
         assert pxp.asarray(self.q).shape == (2, 2)
@@ -443,8 +439,8 @@ def test_ndim_numpy_func(self):
         assert pxp.asarray(self.q).ndim == 2
 
     def test_meshgrid_numpy_func(self):
-        x = [1, 2] * self.ureg.m
-        y = [0, 50, 100] * self.ureg.mm
+        x = pxp.asarray([1, 2]) * self.ureg.m
+        y = pxp.asarray([0, 50, 100]) * self.ureg.mm
         xx, yy = pxp.meshgrid(x, y)
         helpers.assert_quantity_equal(xx, [[1, 2], [1, 2], [1, 2]] * self.ureg.m)
         helpers.assert_quantity_equal(yy, [[0, 0], [50, 50], [100, 100]] * self.ureg.mm)
@@ -466,36 +462,37 @@ def test_where(self):
             pxp.where(self.q >= 2 * self.ureg.m, self.q, 0),
             [[0, 2], [3, 4]] * self.ureg.m,
         )
+        q_float = self.q.astype(float)
         helpers.assert_quantity_equal(
-            pxp.where(self.q >= 2 * self.ureg.m, self.q, pxp.nan),
+            pxp.where(q_float >= 2 * self.ureg.m, q_float, pxp.nan),
             [[pxp.nan, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(self.q >= 3 * self.ureg.m, 0, self.q),
+            pxp.where(q_float >= 3 * self.ureg.m, 0., q_float),
             [[1, 2], [0, 0]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(self.q >= 3 * self.ureg.m, pxp.nan, self.q),
+            pxp.where(q_float >= 3 * self.ureg.m, pxp.nan, q_float),
             [[1, 2], [pxp.nan, pxp.nan]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(self.q >= 2 * self.ureg.m, self.q, pxp.asarray(pxp.nan)),
+            pxp.where(q_float >= 2 * self.ureg.m, q_float, pxp.asarray(pxp.nan)* self.ureg.m),
             [[pxp.nan, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(self.q >= 3 * self.ureg.m, pxp.asarray(pxp.nan), self.q),
+            pxp.where(q_float >= 3 * self.ureg.m, pxp.asarray(pxp.nan)* self.ureg.m, q_float),
             [[1, 2], [pxp.nan, pxp.nan]] * self.ureg.m,
         )
         with pytest.raises(DimensionalityError):
             pxp.where(
-                self.q < 2 * self.ureg.m,
-                self.q,
+                q_float < 2 * self.ureg.m,
+                q_float,
                 0 * self.ureg.J,
             )
 
         helpers.assert_quantity_equal(
-            pxp.where([-1, 0, 1] * self.ureg.m, [1, 2, 1] * self.ureg.s, pxp.nan),
-            [1, pxp.nan, 1] * self.ureg.s,
+            pxp.where(pxp.asarray([-1., 0., 1.]) * self.ureg.m, pxp.asarray([1., 2., 1.]) * self.ureg.s, pxp.nan),
+            pxp.asarray([1., pxp.nan, 1.]) * self.ureg.s,
         )
         with pytest.raises(
             ValueError,
@@ -507,5 +504,16 @@ def test_where(self):
 
     def test_tile(self):
         helpers.assert_quantity_equal(
-            pxp.tile(self.q, 2), pxp.asarray([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m
-        )
+            pxp.tile(pxp.asarray([1,2,3,4]) *self.ureg.m, (4,1)),
+            pxp.asarray([[1, 2, 3, 4],
+                         [1, 2, 3, 4],
+                         [1, 2, 3, 4],
+                         [1, 2, 3, 4]]) * self.ureg.m
+                        )
+        helpers.assert_quantity_equal(
+            pxp.tile(pxp.asarray([[1, 2], [3, 4]]) *self.ureg.m, (2,1)),
+            pxp.asarray([[1, 2],
+                        [3, 4],
+                        [1, 2],
+                        [3, 4]]) * self.ureg.m
+                        )   
\ No newline at end of file

From 93626ba3a0994af69977a3f5936f7d72f8109707 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 5 Jan 2025 15:41:46 +0000
Subject: [PATCH 18/49] tests

---
 src/pint_array/__init__.py |  1 +
 tests/test_array.py        | 79 +++++++++++++++++++-------------------
 2 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index dcbdc9b..e37ca13 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -720,6 +720,7 @@ def linalg_fun(x1, x2, /, **kwargs):
         setattr(mod, name, get_linalg_fun(name))
 
     def matrix_transpose(x):
+        x = asarray(x)
         return x.mT
 
     mod.matrix_transpose = matrix_transpose
diff --git a/tests/test_array.py b/tests/test_array.py
index 4f0532b..5d23986 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -18,7 +18,6 @@
 from pint import UnitRegistry; 
 ureg = UnitRegistry()
 
-# @helpers.requires_numpy
 class TestNumpyMethods:
     @classmethod
     def setup_class(cls):
@@ -62,21 +61,22 @@ def assertNDArrayEqual(self, actual, desired):
 class TestNumpyArrayCreation(TestNumpyMethods):
     # https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html
 
-    # @helpers.requires_array_function_protocol()
+    @pytest.mark.xfail(reason="Scalar arguement issue ")
     def test_ones_like(self):
         self.assertNDArrayEqual(pnp.ones_like(self.q), np.array([[1, 1], [1, 1]]))
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_zeros_like(self):
         self.assertNDArrayEqual(pnp.zeros_like(self.q), np.array([[0, 0], [0, 0]]))
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_empty_like(self):
         ret = pnp.empty_like(self.q)
         assert ret.shape == (2, 2)
-        assert isinstance(ret, np.ndarray)
+        assert isinstance(ret.magnitude, np.ndarray)
 
-    # @helpers.requires_array_function_protocol()
+    
+    @pytest.mark.xfail(reason="Scalar arguement issue ")
     def test_full_like(self):
         helpers.assert_quantity_equal(
             pnp.full_like(self.q, self.Q_(0, self.ureg.degC)),
@@ -108,19 +108,19 @@ def test_reshape(self):
 
     # Transpose-like operations
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_moveaxis(self):
         helpers.assert_quantity_equal(
             pnp.moveaxis(self.q, 1, 0), np.array([[1, 2], [3, 4]]).T * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_transpose(self):
         helpers.assert_quantity_equal(
             pnp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_flip_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
@@ -128,20 +128,20 @@ def test_flip_numpy_func(self):
 
     # Changing number of dimensions
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_broadcast_to(self):
         helpers.assert_quantity_equal(
             pnp.broadcast_to(self.q[:, 1], (2, 2)),
             np.array([[2, 4], [2, 4]]) * self.ureg.m,
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_expand_dims(self):
         helpers.assert_quantity_equal(
             pnp.expand_dims(self.q, 0), np.array([[[1, 2], [3, 4]]]) * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_squeeze(self):
         helpers.assert_quantity_equal(pnp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
@@ -150,7 +150,7 @@ def test_squeeze(self):
 
     # Changing number of dimensions
     # Joining arrays
-    # @helpers.requires_array_function_protocol()
+    
     def test_concat_stack(self, subtests):
         for func in (pnp.concat, pnp.stack):
             with subtests.test(func=func):
@@ -203,7 +203,7 @@ def test_roll(self):
 class TestNumpyMathematicalFunctions(TestNumpyMethods):
     # https://www.numpy.org/devdocs/reference/routines.math.html
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_prod_numpy_func(self):
         axis = 0
         where = [[True, False], [True, True]]
@@ -224,7 +224,7 @@ def test_prod_numpy_func(self):
             pnp.prod(self.q, axis=axis, where=[True, False]), [3, 1] * self.ureg.m**2
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_sum_numpy_func(self):
         helpers.assert_quantity_equal(pnp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
         with pytest.raises(OffsetUnitCalculusError):
@@ -280,7 +280,6 @@ def test_sqrt(self):
         helpers.assert_quantity_equal(pnp.sqrt(q), self.Q_(10, "m"))
 
     @pytest.mark.xfail
-    # @helpers.requires_numpy
     def test_exponentiation_array_exp_2(self):
         arr = np.array(range(3), dtype=float)
         # q = self.Q_(copy.copy(arr), None)
@@ -306,34 +305,34 @@ def test_repeat(self):
             pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_sort_numpy_func(self):
         q = [4, 5, 2, 3, 1, 6] * self.ureg.m
         helpers.assert_quantity_equal(pnp.sort(q), [1, 2, 3, 4, 5, 6] * self.ureg.m)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_argsort_numpy_func(self):
         self.assertNDArrayEqual(pnp.argsort(self.q, axis=0), np.array([[0, 0], [1, 1]]))
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_searchsorted_numpy_func(self):
         """Test searchsorted as numpy function."""
         q = self.q.flatten()
         self.assertNDArrayEqual(pnp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_nonzero_numpy_func(self):
         q = [1, 0, 5, 6, 0, 9] * self.ureg.m
         self.assertNDArrayEqual(pnp.nonzero(q)[0], [0, 2, 3, 5])
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_any_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert pnp.any(q)
         with pytest.raises(ValueError):
             pnp.any(self.q_temperature)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_all_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert not pnp.all(q)
@@ -343,18 +342,18 @@ def test_all_numpy_func(self):
     def test_max_numpy_func(self):
         assert pnp.max(self.q) == 4 * self.ureg.m
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_max_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.max(self.q, axis=1), [2, 4] * self.ureg.m)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_max_with_initial_arg(self):
         helpers.assert_quantity_equal(
             pnp.max(self.q[..., None], axis=2, initial=3 * self.ureg.m),
             [[3, 3], [3, 4]] * self.ureg.m,
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_argmax_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmax(self.q, axis=0), np.array([1, 1]))
 
@@ -363,22 +362,22 @@ def test_maximum(self):
             pnp.maximum(self.q, self.Q_([0, 5], "m")), self.Q_([[1, 5], [3, 5]], "m")
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_min_numpy_func(self):
         assert pnp.min(self.q) == 1 * self.ureg.m
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_min_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.min(self.q, axis=1), [1, 3] * self.ureg.m)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_min_with_initial_arg(self):
         helpers.assert_quantity_equal(
             pnp.min(self.q[..., None], axis=2, initial=3 * self.ureg.m),
             [[1, 2], [3, 3]] * self.ureg.m,
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_argmin_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmin(self.q, axis=0), np.array([0, 0]))
 
@@ -387,35 +386,35 @@ def test_minimum(self):
             pnp.minimum(self.q, self.Q_([0, 5], "m")), self.Q_([[0, 2], [0, 4]], "m")
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_clip_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_round_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_cumulative_sum(self):
         helpers.assert_quantity_equal(
             pnp.cumulative_sum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_mean_numpy_func(self):
         assert pnp.mean(self.q) == 2.5 * self.ureg.m
         assert pnp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_var_numpy_func(self):
         assert pnp.var(self.q) == 1.25 * self.ureg.m**2
         assert pnp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_std_numpy_func(self):
         helpers.assert_quantity_almost_equal(
             pnp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
@@ -520,15 +519,15 @@ def test_dtype(self):
 
         assert u.dtype == "uint32"
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_shape_numpy_func(self):
         assert pnp.asarray(self.q).shape == (2, 2)
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_ndim_numpy_func(self):
         assert pnp.asarray(self.q).ndim == 2
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_meshgrid_numpy_func(self):
         x = [1, 2] * self.ureg.m
         y = [0, 50, 100] * self.ureg.mm
@@ -544,7 +543,7 @@ def test_comparisons(self):
             self.q < 2 * self.ureg.m, np.array([[True, False], [False, False]])
         )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_where(self):
         helpers.assert_quantity_equal(
             pnp.where(self.q >= 2 * self.ureg.m, self.q, 20 * self.ureg.m),
@@ -593,7 +592,7 @@ def test_where(self):
                 self.ureg.Quantity([-1, 0, 1], "degC"), [1, 2, 1] * self.ureg.s, pnp.nan
             )
 
-    # @helpers.requires_array_function_protocol()
+    
     def test_tile(self):
         helpers.assert_quantity_equal(
             pnp.tile(self.q, 2), np.array([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m

From 1645d7b7c002357277e124749ad0cd4cf80c296f Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sat, 11 Jan 2025 20:36:24 +0000
Subject: [PATCH 19/49] rebase

---
 src/pint_array/__init__.py |  5 ++---
 tests/test_array.py        | 28 +++++++++++++++++-----------
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index e37ca13..169a111 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -623,18 +623,17 @@ def fun(x, /, *args, func_str=func_str, **kwargs):
             return ArrayUnitQuantity(magnitude, x.units)
 
         setattr(mod, func_str, fun)
-    
+
     for func_str in ["sqrt"]:
 
         def fun(x, /, *args, func_str=func_str, **kwargs):
             x = asarray(x)
             magnitude = xp.asarray(x.magnitude, copy=True)
             magnitude = getattr(xp, func_str)(magnitude, *args, **kwargs)
-            return ArrayUnitQuantity(magnitude, x.units ** 0.5)
+            return ArrayUnitQuantity(magnitude, x.units**0.5)
 
         setattr(mod, func_str, fun)
 
-
     elementwise_two_arrays = [
         "add",
         "atan2",
diff --git a/tests/test_array.py b/tests/test_array.py
index 5d23986..2f6c5a1 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -3,21 +3,26 @@
 import copy
 import operator as op
 import pickle
-import warnings
 
+import numpy as np
 import pytest
+from pint import DimensionalityError, OffsetUnitCalculusError
 
-from pint import DimensionalityError, OffsetUnitCalculusError, UnitStrippedWarning
 # from pint.compat import np
 from pint.testsuite import helpers
-from pint.testsuite.test_umath import TestUFuncs
 
-import pint_array; 
-import numpy as np; 
-pnp = pint_array.pint_namespace(np); 
-from pint import UnitRegistry; 
+import pint_array
+
+pnp = pint_array.pint_namespace(np)
+from pint import UnitRegistry
+
 ureg = UnitRegistry()
 
+<<<<<<< HEAD
+=======
+
+# @helpers.requires_numpy
+>>>>>>> 1ad9ca9 (style: pre-commit fixes)
 class TestNumpyMethods:
     @classmethod
     def setup_class(cls):
@@ -98,7 +103,7 @@ def test_flatten(self):
         helpers.assert_quantity_equal(self.q.flatten(), [1, 2, 3, 4] * self.ureg.m)
 
     def test_flat(self):
-        for q, v in zip(self.q.flat, [1, 2, 3, 4]):
+        for q, v in zip(self.q.flat, [1, 2, 3, 4], strict=False):
             assert q == v * self.ureg.m
 
     def test_reshape(self):
@@ -212,7 +217,9 @@ def test_prod_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.prod(self.q, axis=axis), [3, 8] * self.ureg.m**2
         )
-        helpers.assert_quantity_equal(pnp.prod(self.q, where=where), 12 * self.ureg.m**3)
+        helpers.assert_quantity_equal(
+            pnp.prod(self.q, where=where), 12 * self.ureg.m**3
+        )
 
         with pytest.raises(DimensionalityError):
             pnp.prod(self.q, axis=axis, where=where)
@@ -299,7 +306,6 @@ def test_exponentiation_array_exp_2(self):
 
 
 class TestNumpyUnclassified(TestNumpyMethods):
-
     def test_repeat(self):
         helpers.assert_quantity_equal(
             pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
@@ -513,7 +519,7 @@ def test_equal(self):
         self.assertNDArrayEqual(v == w, false)
         self.assertNDArrayEqual(v == w.to("mm"), false)
         self.assertNDArrayEqual(u == v, false)
-    
+
     def test_dtype(self):
         u = self.Q_(pnp.arange(12, dtype="uint32"))
 

From 219cc8e8dcac21e86a0721f81483c746ebcf43a3 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Sun, 5 Jan 2025 15:43:00 +0000
Subject: [PATCH 20/49] style: pre-commit fixes

---
 tests/test_array.py | 41 +++++------------------------------------
 1 file changed, 5 insertions(+), 36 deletions(-)

diff --git a/tests/test_array.py b/tests/test_array.py
index 2f6c5a1..dae6fea 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -18,11 +18,15 @@
 
 ureg = UnitRegistry()
 
+<<<<<<< HEAD
 <<<<<<< HEAD
 =======
 
 # @helpers.requires_numpy
 >>>>>>> 1ad9ca9 (style: pre-commit fixes)
+=======
+
+>>>>>>> 8498256 (style: pre-commit fixes)
 class TestNumpyMethods:
     @classmethod
     def setup_class(cls):
@@ -70,17 +74,14 @@ class TestNumpyArrayCreation(TestNumpyMethods):
     def test_ones_like(self):
         self.assertNDArrayEqual(pnp.ones_like(self.q), np.array([[1, 1], [1, 1]]))
 
-    
     def test_zeros_like(self):
         self.assertNDArrayEqual(pnp.zeros_like(self.q), np.array([[0, 0], [0, 0]]))
 
-    
     def test_empty_like(self):
         ret = pnp.empty_like(self.q)
         assert ret.shape == (2, 2)
         assert isinstance(ret.magnitude, np.ndarray)
 
-    
     @pytest.mark.xfail(reason="Scalar arguement issue ")
     def test_full_like(self):
         helpers.assert_quantity_equal(
@@ -113,19 +114,16 @@ def test_reshape(self):
 
     # Transpose-like operations
 
-    
     def test_moveaxis(self):
         helpers.assert_quantity_equal(
             pnp.moveaxis(self.q, 1, 0), np.array([[1, 2], [3, 4]]).T * self.ureg.m
         )
 
-    
     def test_transpose(self):
         helpers.assert_quantity_equal(
             pnp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
         )
 
-    
     def test_flip_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
@@ -133,20 +131,17 @@ def test_flip_numpy_func(self):
 
     # Changing number of dimensions
 
-    
     def test_broadcast_to(self):
         helpers.assert_quantity_equal(
             pnp.broadcast_to(self.q[:, 1], (2, 2)),
             np.array([[2, 4], [2, 4]]) * self.ureg.m,
         )
 
-    
     def test_expand_dims(self):
         helpers.assert_quantity_equal(
             pnp.expand_dims(self.q, 0), np.array([[[1, 2], [3, 4]]]) * self.ureg.m
         )
 
-    
     def test_squeeze(self):
         helpers.assert_quantity_equal(pnp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
@@ -155,7 +150,7 @@ def test_squeeze(self):
 
     # Changing number of dimensions
     # Joining arrays
-    
+
     def test_concat_stack(self, subtests):
         for func in (pnp.concat, pnp.stack):
             with subtests.test(func=func):
@@ -208,7 +203,6 @@ def test_roll(self):
 class TestNumpyMathematicalFunctions(TestNumpyMethods):
     # https://www.numpy.org/devdocs/reference/routines.math.html
 
-    
     def test_prod_numpy_func(self):
         axis = 0
         where = [[True, False], [True, True]]
@@ -231,7 +225,6 @@ def test_prod_numpy_func(self):
             pnp.prod(self.q, axis=axis, where=[True, False]), [3, 1] * self.ureg.m**2
         )
 
-    
     def test_sum_numpy_func(self):
         helpers.assert_quantity_equal(pnp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
         with pytest.raises(OffsetUnitCalculusError):
@@ -311,34 +304,28 @@ def test_repeat(self):
             pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
         )
 
-    
     def test_sort_numpy_func(self):
         q = [4, 5, 2, 3, 1, 6] * self.ureg.m
         helpers.assert_quantity_equal(pnp.sort(q), [1, 2, 3, 4, 5, 6] * self.ureg.m)
 
-    
     def test_argsort_numpy_func(self):
         self.assertNDArrayEqual(pnp.argsort(self.q, axis=0), np.array([[0, 0], [1, 1]]))
 
-    
     def test_searchsorted_numpy_func(self):
         """Test searchsorted as numpy function."""
         q = self.q.flatten()
         self.assertNDArrayEqual(pnp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
 
-    
     def test_nonzero_numpy_func(self):
         q = [1, 0, 5, 6, 0, 9] * self.ureg.m
         self.assertNDArrayEqual(pnp.nonzero(q)[0], [0, 2, 3, 5])
 
-    
     def test_any_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert pnp.any(q)
         with pytest.raises(ValueError):
             pnp.any(self.q_temperature)
 
-    
     def test_all_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert not pnp.all(q)
@@ -348,18 +335,15 @@ def test_all_numpy_func(self):
     def test_max_numpy_func(self):
         assert pnp.max(self.q) == 4 * self.ureg.m
 
-    
     def test_max_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.max(self.q, axis=1), [2, 4] * self.ureg.m)
 
-    
     def test_max_with_initial_arg(self):
         helpers.assert_quantity_equal(
             pnp.max(self.q[..., None], axis=2, initial=3 * self.ureg.m),
             [[3, 3], [3, 4]] * self.ureg.m,
         )
 
-    
     def test_argmax_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmax(self.q, axis=0), np.array([1, 1]))
 
@@ -368,22 +352,18 @@ def test_maximum(self):
             pnp.maximum(self.q, self.Q_([0, 5], "m")), self.Q_([[1, 5], [3, 5]], "m")
         )
 
-    
     def test_min_numpy_func(self):
         assert pnp.min(self.q) == 1 * self.ureg.m
 
-    
     def test_min_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.min(self.q, axis=1), [1, 3] * self.ureg.m)
 
-    
     def test_min_with_initial_arg(self):
         helpers.assert_quantity_equal(
             pnp.min(self.q[..., None], axis=2, initial=3 * self.ureg.m),
             [[1, 2], [3, 3]] * self.ureg.m,
         )
 
-    
     def test_argmin_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmin(self.q, axis=0), np.array([0, 0]))
 
@@ -392,35 +372,29 @@ def test_minimum(self):
             pnp.minimum(self.q, self.Q_([0, 5], "m")), self.Q_([[0, 2], [0, 4]], "m")
         )
 
-    
     def test_clip_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
         )
 
-    
     def test_round_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
         )
 
-    
     def test_cumulative_sum(self):
         helpers.assert_quantity_equal(
             pnp.cumulative_sum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
         )
 
-    
     def test_mean_numpy_func(self):
         assert pnp.mean(self.q) == 2.5 * self.ureg.m
         assert pnp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
 
-    
     def test_var_numpy_func(self):
         assert pnp.var(self.q) == 1.25 * self.ureg.m**2
         assert pnp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
 
-    
     def test_std_numpy_func(self):
         helpers.assert_quantity_almost_equal(
             pnp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
@@ -525,15 +499,12 @@ def test_dtype(self):
 
         assert u.dtype == "uint32"
 
-    
     def test_shape_numpy_func(self):
         assert pnp.asarray(self.q).shape == (2, 2)
 
-    
     def test_ndim_numpy_func(self):
         assert pnp.asarray(self.q).ndim == 2
 
-    
     def test_meshgrid_numpy_func(self):
         x = [1, 2] * self.ureg.m
         y = [0, 50, 100] * self.ureg.mm
@@ -549,7 +520,6 @@ def test_comparisons(self):
             self.q < 2 * self.ureg.m, np.array([[True, False], [False, False]])
         )
 
-    
     def test_where(self):
         helpers.assert_quantity_equal(
             pnp.where(self.q >= 2 * self.ureg.m, self.q, 20 * self.ureg.m),
@@ -598,7 +568,6 @@ def test_where(self):
                 self.ureg.Quantity([-1, 0, 1], "degC"), [1, 2, 1] * self.ureg.s, pnp.nan
             )
 
-    
     def test_tile(self):
         helpers.assert_quantity_equal(
             pnp.tile(self.q, 2), np.array([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m

From 80b05ab6b041056e931ec99cc65137a8bd11628d Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 5 Jan 2025 16:55:28 +0000
Subject: [PATCH 21/49] remove parts not in spec

---
 src/pint_array/__init__.py |  1 +
 tests/test_array.py        | 46 +++++++++-----------------------------
 2 files changed, 11 insertions(+), 36 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 169a111..4172954 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -339,6 +339,7 @@ def manip_fun(x, *args, **kwargs):
                 args[0] = repeats.magnitude
 
             if func_str in arbitrary_num_arrays and not one_array:
+                args = [asarray(arg, units = x[0].units).magnitude for arg in args]
                 magnitude = xp_func(*magnitude, *args, **kwargs)
             else:
                 magnitude = xp_func(magnitude, *args, **kwargs)
diff --git a/tests/test_array.py b/tests/test_array.py
index dae6fea..843c7f6 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -158,10 +158,10 @@ def test_concat_stack(self, subtests):
                     func([self.q] * 2), self.Q_(func([self.q.m] * 2), self.ureg.m)
                 )
                 # One or more of the args is a bare array full of zeros or NaNs
-                helpers.assert_quantity_equal(
-                    func([self.q_zero_or_nan.m, self.q]),
-                    self.Q_(func([self.q_zero_or_nan.m, self.q.m]), self.ureg.m),
-                )
+                # helpers.assert_quantity_equal(
+                #     func([self.q_zero_or_nan.m, self.q]),
+                #     self.Q_(func([self.q_zero_or_nan.m, self.q.m]), self.ureg.m),
+                # )
                 # One or more of the args is a bare array with at least one non-zero,
                 # non-NaN element
                 nz = self.q_zero_or_nan
@@ -182,14 +182,13 @@ def test_broadcast_arrays(self):
         x = self.Q_(np.array([[1, 2, 3]]), "m")
         y = self.Q_(np.array([[4], [5]]), "nm")
         result = pnp.broadcast_arrays(x, y)
-        expected = self.Q_(
-            [
-                [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]],
-                [[4e-09, 4e-09, 4e-09], [5e-09, 5e-09, 5e-09]],
-            ],
-            "m",
+        expected = (self.Q_(np.array([[1, 2, 3],
+                         [1, 2, 3]]),"m"),
+                    self.Q_(np.array([[4, 4, 4],
+                         [5, 5, 5]]),"nm")
         )
-        helpers.assert_quantity_equal(result, expected)
+        helpers.assert_quantity_equal(result[0], expected[0])
+        helpers.assert_quantity_equal(result[1], expected[1])
 
         result = pnp.broadcast_arrays(x, y, subok=True)
         helpers.assert_quantity_equal(result, expected)
@@ -211,19 +210,6 @@ def test_prod_numpy_func(self):
         helpers.assert_quantity_equal(
             pnp.prod(self.q, axis=axis), [3, 8] * self.ureg.m**2
         )
-        helpers.assert_quantity_equal(
-            pnp.prod(self.q, where=where), 12 * self.ureg.m**3
-        )
-
-        with pytest.raises(DimensionalityError):
-            pnp.prod(self.q, axis=axis, where=where)
-        helpers.assert_quantity_equal(
-            pnp.prod(self.q, axis=axis, where=[[True, False], [False, True]]),
-            [1, 4] * self.ureg.m,
-        )
-        helpers.assert_quantity_equal(
-            pnp.prod(self.q, axis=axis, where=[True, False]), [3, 1] * self.ureg.m**2
-        )
 
     def test_sum_numpy_func(self):
         helpers.assert_quantity_equal(pnp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
@@ -338,12 +324,6 @@ def test_max_numpy_func(self):
     def test_max_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.max(self.q, axis=1), [2, 4] * self.ureg.m)
 
-    def test_max_with_initial_arg(self):
-        helpers.assert_quantity_equal(
-            pnp.max(self.q[..., None], axis=2, initial=3 * self.ureg.m),
-            [[3, 3], [3, 4]] * self.ureg.m,
-        )
-
     def test_argmax_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmax(self.q, axis=0), np.array([1, 1]))
 
@@ -358,12 +338,6 @@ def test_min_numpy_func(self):
     def test_min_with_axis_arg(self):
         helpers.assert_quantity_equal(pnp.min(self.q, axis=1), [1, 3] * self.ureg.m)
 
-    def test_min_with_initial_arg(self):
-        helpers.assert_quantity_equal(
-            pnp.min(self.q[..., None], axis=2, initial=3 * self.ureg.m),
-            [[1, 2], [3, 3]] * self.ureg.m,
-        )
-
     def test_argmin_numpy_func(self):
         self.assertNDArrayEqual(pnp.argmin(self.q, axis=0), np.array([0, 0]))
 

From ae6b585ed7517c056dcc5264af3a07bb40436342 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Sun, 5 Jan 2025 16:55:47 +0000
Subject: [PATCH 22/49] style: pre-commit fixes

---
 src/pint_array/__init__.py | 2 +-
 tests/test_array.py        | 7 +++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 4172954..773f04b 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -339,7 +339,7 @@ def manip_fun(x, *args, **kwargs):
                 args[0] = repeats.magnitude
 
             if func_str in arbitrary_num_arrays and not one_array:
-                args = [asarray(arg, units = x[0].units).magnitude for arg in args]
+                args = [asarray(arg, units=x[0].units).magnitude for arg in args]
                 magnitude = xp_func(*magnitude, *args, **kwargs)
             else:
                 magnitude = xp_func(magnitude, *args, **kwargs)
diff --git a/tests/test_array.py b/tests/test_array.py
index 843c7f6..fe2d185 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -182,10 +182,9 @@ def test_broadcast_arrays(self):
         x = self.Q_(np.array([[1, 2, 3]]), "m")
         y = self.Q_(np.array([[4], [5]]), "nm")
         result = pnp.broadcast_arrays(x, y)
-        expected = (self.Q_(np.array([[1, 2, 3],
-                         [1, 2, 3]]),"m"),
-                    self.Q_(np.array([[4, 4, 4],
-                         [5, 5, 5]]),"nm")
+        expected = (
+            self.Q_(np.array([[1, 2, 3], [1, 2, 3]]), "m"),
+            self.Q_(np.array([[4, 4, 4], [5, 5, 5]]), "nm"),
         )
         helpers.assert_quantity_equal(result[0], expected[0])
         helpers.assert_quantity_equal(result[1], expected[1])

From 8b9f25255336fd79cdfa440b01ebe57b2a4f1faa Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 5 Jan 2025 17:38:01 +0000
Subject: [PATCH 23/49] tets

---
 src/pint_array/__init__.py | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 773f04b..bb892ef 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -474,10 +474,23 @@ def searchsorted(x1, x2, /, *, side="left", sorter=None):
 
     # ignore units of condition, convert x2 to units of x1
     def where(condition, x1, x2, /):
+        if not getattr(condition, "_is_multiplicative", True):
+            raise ValueError(
+                "Invalid units of the condition: Boolean value of Quantity with offset unit is ambiguous."
+            )
+
         condition = asarray(condition)
-        x1 = asarray(x1)
-        x2 = asarray(x2)
+        if hasattr(x1, "units") and hasattr(x2, "units"):
+            x1 = asarray(x1)
+            x2 = asarray(x2)
+        elif hasattr(x1, "units"):
+            x1 = asarray(x1)
+            x2 = asarray(x2, units=x1.units)
+        elif hasattr(x2, "units"):
+            x1 = asarray(x1, units=x2.units)
+            x2 = asarray(x2)
         units = x1.units
+        print(x2.m_as(units))
         magnitude = xp.where(condition.magnitude, x1.magnitude, x2.m_as(units))
         return ArrayUnitQuantity(magnitude, units)
 

From 4b36af39bfb86d39f3e0f17d74d91300db20a08e Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 5 Jan 2025 23:29:03 +0000
Subject: [PATCH 24/49] implementations

---
 src/pint_array/__init__.py | 39 +++++++++++++++++++++++++++++++++++---
 tests/test_array.py        | 10 ----------
 2 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index bb892ef..06d5bf9 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -17,6 +17,7 @@
 from array_api_compat import size
 from pint import Quantity
 from pint.facets.plain import MagnitudeT, PlainQuantity
+from pint import DimensionalityError, OffsetUnitCalculusError
 
 __version__ = "0.0.1.dev0"
 __all__ = ["__version__", "pint_namespace"]
@@ -352,7 +353,7 @@ def manip_fun(x, *args, **kwargs):
 
         return manip_fun
 
-    creation_manip_functions = ["tril", "triu", "meshgrid"]
+    creation_manip_functions = ["tril", "triu"]
     manip_names = [
         "broadcast_arrays",
         "broadcast_to",
@@ -372,6 +373,19 @@ def manip_fun(x, *args, **kwargs):
     for name in manip_names + creation_manip_functions:
         setattr(mod, name, get_manip_fun(name))
 
+    def _meshgrid(*xi, **kwargs):
+        # Simply need to map input units to onto list of outputs
+        input_units = (x.units for x in xi)
+        res = xp.meshgrid(*(x.magnitude for x in xi), **kwargs)
+        return [out * unit for out, unit in zip(res, input_units)]
+    mod.meshgrid = _meshgrid
+    
+    def _broadcast_arrays(*arrays):
+        arrays = [asarray(array) for array in arrays]
+        res = xp.broadcast_arrays(*[array.magnitude for array in arrays])
+        return [ArrayUnitQuantity(magnitude, array.units) for magnitude, array in zip(res, arrays)]
+    mod.broadcast_arrays = _broadcast_arrays
+
     ## Data Type Functions and Data Types ##
     dtype_fun_names = ["can_cast", "finfo", "iinfo", "result_type"]
     for func_str in dtype_fun_names:
@@ -671,9 +685,7 @@ def fun(x, /, *args, func_str=func_str, **kwargs):
         "logical_xor",
         "maximum",
         "minimum",
-        "multiply",
         "not_equal",
-        "pow",
         "remainder",
         "subtract",
     ]
@@ -708,6 +720,27 @@ def multiply(x1, x2, /, *args, **kwargs):
 
     mod.multiply = multiply
 
+
+    def pow(x1, x2, /, *args, **kwargs):
+        x1 = asarray(x1)
+        x2 = asarray(x2)
+
+        if not x2.units.dimensionless:
+            raise DimensionalityError(x2.units, "dimensionless")
+        if x2.ndim > 0 and not xp.all(x2.magnitude == x2[0].magnitude):
+            raise DimensionalityError(
+                        x2.units,
+                        "dimensionless",
+                        extra_msg="The exponent must be a scalar or an array of all the same value.",
+                    )
+
+        units = x1.units ** x2.magnitude
+
+        magnitude = xp.pow(x1.magnitude, x2.magnitude, *args, **kwargs)
+        return ArrayUnitQuantity(magnitude, units)
+
+    mod.pow = pow
+
     ## Indexing Functions
     def take(x, indices, /, **kwargs):
         magnitude = xp.take(x.magnitude, indices.magnitude, **kwargs)
diff --git a/tests/test_array.py b/tests/test_array.py
index fe2d185..040730c 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -186,10 +186,6 @@ def test_broadcast_arrays(self):
             self.Q_(np.array([[1, 2, 3], [1, 2, 3]]), "m"),
             self.Q_(np.array([[4, 4, 4], [5, 5, 5]]), "nm"),
         )
-        helpers.assert_quantity_equal(result[0], expected[0])
-        helpers.assert_quantity_equal(result[1], expected[1])
-
-        result = pnp.broadcast_arrays(x, y, subok=True)
         helpers.assert_quantity_equal(result, expected)
 
     def test_roll(self):
@@ -243,7 +239,6 @@ def test_power(self):
             with pytest.raises(DimensionalityError):
                 op_(2.0, q_cp)
             arr_cp = copy.copy(arr)
-            arr_cp = copy.copy(arr)
             q_cp = copy.copy(q)
             with pytest.raises(DimensionalityError):
                 op_(q_cp, arr_cp)
@@ -376,11 +371,6 @@ def test_std_numpy_func(self):
             pnp.std(self.q_temperature), 1.11803 * self.ureg.delta_degC, rtol=1e-5
         )
 
-    def test_cumprod(self):
-        with pytest.raises(DimensionalityError):
-            self.q.cumprod()
-        helpers.assert_quantity_equal((self.q / self.ureg.m).cumprod(), [1, 2, 6, 24])
-
     def test_conj(self):
         helpers.assert_quantity_equal((self.q * (1 + 1j)).conj(), self.q * (1 - 1j))
         helpers.assert_quantity_equal(

From b71d11e7966dae29ea29fe06cb963c67ad4aa29f Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Sun, 5 Jan 2025 23:29:13 +0000
Subject: [PATCH 25/49] style: pre-commit fixes

---
 src/pint_array/__init__.py | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 06d5bf9..c6f4fcb 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -15,9 +15,8 @@
 from typing import Generic
 
 from array_api_compat import size
-from pint import Quantity
+from pint import DimensionalityError, OffsetUnitCalculusError, Quantity
 from pint.facets.plain import MagnitudeT, PlainQuantity
-from pint import DimensionalityError, OffsetUnitCalculusError
 
 __version__ = "0.0.1.dev0"
 __all__ = ["__version__", "pint_namespace"]
@@ -377,13 +376,18 @@ def _meshgrid(*xi, **kwargs):
         # Simply need to map input units to onto list of outputs
         input_units = (x.units for x in xi)
         res = xp.meshgrid(*(x.magnitude for x in xi), **kwargs)
-        return [out * unit for out, unit in zip(res, input_units)]
+        return [out * unit for out, unit in zip(res, input_units, strict=False)]
+
     mod.meshgrid = _meshgrid
-    
+
     def _broadcast_arrays(*arrays):
         arrays = [asarray(array) for array in arrays]
         res = xp.broadcast_arrays(*[array.magnitude for array in arrays])
-        return [ArrayUnitQuantity(magnitude, array.units) for magnitude, array in zip(res, arrays)]
+        return [
+            ArrayUnitQuantity(magnitude, array.units)
+            for magnitude, array in zip(res, arrays, strict=False)
+        ]
+
     mod.broadcast_arrays = _broadcast_arrays
 
     ## Data Type Functions and Data Types ##
@@ -720,7 +724,6 @@ def multiply(x1, x2, /, *args, **kwargs):
 
     mod.multiply = multiply
 
-
     def pow(x1, x2, /, *args, **kwargs):
         x1 = asarray(x1)
         x2 = asarray(x2)
@@ -729,12 +732,12 @@ def pow(x1, x2, /, *args, **kwargs):
             raise DimensionalityError(x2.units, "dimensionless")
         if x2.ndim > 0 and not xp.all(x2.magnitude == x2[0].magnitude):
             raise DimensionalityError(
-                        x2.units,
-                        "dimensionless",
-                        extra_msg="The exponent must be a scalar or an array of all the same value.",
-                    )
+                x2.units,
+                "dimensionless",
+                extra_msg="The exponent must be a scalar or an array of all the same value.",
+            )
 
-        units = x1.units ** x2.magnitude
+        units = x1.units**x2.magnitude
 
         magnitude = xp.pow(x1.magnitude, x2.magnitude, *args, **kwargs)
         return ArrayUnitQuantity(magnitude, units)

From f509f0d67d599db2ecea796f0ff7fedac17cc114 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 5 Jan 2025 23:32:06 +0000
Subject: [PATCH 26/49] dependency

---
 pyproject.toml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/pyproject.toml b/pyproject.toml
index ae4be4b..91de1ce 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -40,6 +40,7 @@ ipython = "ipython"
 
 [tool.pixi.feature.tests.dependencies]
 pytest = "*"
+pytest-subtests = "*"
 
 [tool.pixi.feature.tests.tasks]
 tests = "pytest"

From ef52c794be1f48f59d0b0378c4c30138fa962b1e Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Mon, 6 Jan 2025 11:57:21 +0000
Subject: [PATCH 27/49] update lockfile

---
 pixi.lock | 119 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 75 insertions(+), 44 deletions(-)

diff --git a/pixi.lock b/pixi.lock
index ab1b665..96579da 100644
--- a/pixi.lock
+++ b/pixi.lock
@@ -42,7 +42,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ndindex-1.9.2-py310ha75aee5_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py310h5851e9f_0.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -50,6 +50,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python-3.10.16-he725a3c_1_cpython.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.10-5_cp310.conda
       - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8228510_1.conda
@@ -89,7 +90,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/ndindex-1.8-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py310ha1ddda0_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -97,6 +98,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.10.16-h870587a_1_cpython.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python_abi-3.10-5_cp310.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda
@@ -136,7 +138,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda
       - conda: https://prefix.dev/conda-forge/win-64/ndindex-1.9.2-py310ha8f682b_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.1-py310hb9d903e_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -144,6 +146,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/python-3.10.16-h37870fc_1_cpython.conda
       - conda: https://prefix.dev/conda-forge/win-64/python_abi-3.10-5_cp310.conda
       - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
@@ -201,7 +204,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ndindex-1.9.2-py313h536fd9c_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py313hb30382a_0.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -209,6 +212,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8228510_1.conda
@@ -250,7 +254,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/ndindex-1.8-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py313ha4a2180_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -258,6 +262,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda
@@ -299,7 +304,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda
       - conda: https://prefix.dev/conda-forge/win-64/ndindex-1.9.2-py313ha7868ed_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.1-py313hd65a2fa_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -307,6 +312,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
@@ -357,7 +363,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py313hb30382a_0.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_102_cp313.conda
@@ -391,7 +397,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.6-hdb05f8b_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py313ha4a2180_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_102_cp313.conda
@@ -425,7 +431,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda
       - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda
       - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.1-py313hd65a2fa_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_102_cp313.conda
@@ -467,7 +473,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
-      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.4-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/ipython-8.31.0-pyh707e725_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda
@@ -494,7 +500,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/ndindex-1.9.2-py313h536fd9c_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py313hb30382a_0.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda
@@ -511,6 +517,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/pyyaml-6.0.2-py313h536fd9c_1.conda
@@ -525,7 +532,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ukkonen-1.0.1-py313h33d0bda_5.conda
-      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.0-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2
       - pypi: .
@@ -548,7 +555,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
-      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.4-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/ipython-8.31.0-pyh707e725_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda
@@ -571,7 +578,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/ndindex-1.8-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py313ha4a2180_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda
@@ -588,6 +595,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/pyyaml-6.0.2-py313h20a7fcf_1.conda
@@ -602,7 +610,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/ukkonen-1.0.1-py313hf9c7212_5.conda
-      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.0-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2
       - pypi: .
@@ -625,7 +633,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
-      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.4-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda
       - conda: https://prefix.dev/conda-forge/noarch/ipython-8.31.0-pyh7428d3b_0.conda
@@ -648,7 +656,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/ndindex-1.9.2-py313ha7868ed_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.1-py313hd65a2fa_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda
@@ -663,6 +671,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_102_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/pyyaml-6.0.2-py313ha7868ed_1.conda
@@ -680,7 +689,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/ukkonen-1.0.1-py313h1ec8472_5.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-ha32ba9b_23.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.42.34433-he29a5d6_23.conda
-      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.0-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/vs2015_runtime-14.42.34433-hdffcdeb_23.conda
       - conda: https://prefix.dev/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2
@@ -713,6 +722,7 @@ packages:
   depends:
   - python >=3.9
   license: MIT
+  license_family: MIT
   purls:
   - pkg:pypi/array-api-compat?source=hash-mapping
   size: 38442
@@ -724,6 +734,7 @@ packages:
   - numpy
   - python >=3.9
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/array-api-strict?source=hash-mapping
   size: 53675
@@ -990,13 +1001,14 @@ packages:
   - setuptools
   - sortedcontainers >=2.1.0,<3.0.0
   license: MPL-2.0
+  license_family: MOZILLA
   purls:
   - pkg:pypi/hypothesis?source=hash-mapping
   size: 341990
   timestamp: 1735341651189
-- conda: https://prefix.dev/conda-forge/noarch/identify-2.6.4-pyhd8ed1ab_0.conda
-  sha256: 8acc3bfc7781ea1ddc8c013faff5106a0539e5671e31bee0d81011a1e2df20d8
-  md5: 5ec16e7ad9bab911ff0696940953f505
+- conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
+  sha256: e8ea11b8e39a98a9c34efb5c21c3fca718e31e1f41fd9ae5f6918b8eb402da59
+  md5: c1b0f663ff141265d1be1242259063f0
   depends:
   - python >=3.9
   - ukkonen
@@ -1004,8 +1016,8 @@ packages:
   license_family: MIT
   purls:
   - pkg:pypi/identify?source=hash-mapping
-  size: 78570
-  timestamp: 1735518781514
+  size: 78415
+  timestamp: 1736026672643
 - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
   sha256: 0ec8f4d02053cd03b0f3e63168316530949484f80e16f5e2fb199a1d117a89ca
   md5: 6837f3eff7dcea42ecd714ce1ac2b108
@@ -1796,6 +1808,7 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 7912254
@@ -1815,6 +1828,7 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 8478406
@@ -1834,6 +1848,7 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 5929029
@@ -1853,6 +1868,7 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 6513050
@@ -1872,6 +1888,7 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 6420026
@@ -1891,13 +1908,14 @@ packages:
   constrains:
   - numpy-base <0a0
   license: BSD-3-Clause
+  license_family: BSD
   purls:
   - pkg:pypi/numpy?source=hash-mapping
   size: 7147174
   timestamp: 1734905243335
-- conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda
-  sha256: 814b9dff1847b132c676ee6cc1a8cb2d427320779b93e1b6d76552275c128705
-  md5: 23cc74f77eb99315c0360ec3533147a9
+- conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
+  sha256: f62f6bca4a33ca5109b6d571b052a394d836956d21b25b7ffd03376abf7a481f
+  md5: 4ce6875f75469b2757a65e10a5d05e31
   depends:
   - __glibc >=2.17,<3.0.a0
   - ca-certificates
@@ -1905,22 +1923,22 @@ packages:
   license: Apache-2.0
   license_family: Apache
   purls: []
-  size: 2947466
-  timestamp: 1731377666602
-- conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda
-  sha256: bd1d58ced46e75efa3b842c61642fd12272c69e9fe4d7261078bc082153a1d53
-  md5: df307bbc703324722df0293c9ca2e418
+  size: 2937158
+  timestamp: 1736086387286
+- conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
+  sha256: 97772762abc70b3a537683ca9fc3ff3d6099eb64e4aba3b9c99e6fce48422d21
+  md5: 22f971393637480bda8c679f374d8861
   depends:
   - __osx >=11.0
   - ca-certificates
   license: Apache-2.0
   license_family: Apache
   purls: []
-  size: 2935176
-  timestamp: 1731377561525
-- conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda
-  sha256: e03045a0837e01ff5c75e9273a572553e7522290799807f918c917a9826a6484
-  md5: d0d805d9b5524a14efb51b3bff965e83
+  size: 2936415
+  timestamp: 1736086108693
+- conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
+  sha256: 519a06eaab7c878fbebb8cab98ea4a4465eafb1e9ed8c6ce67226068a80a92f0
+  md5: fb45308ba8bfe1abf1f4a27bad24a743
   depends:
   - ca-certificates
   - ucrt >=10.0.20348.0
@@ -1929,8 +1947,8 @@ packages:
   license: Apache-2.0
   license_family: Apache
   purls: []
-  size: 8491156
-  timestamp: 1731379715927
+  size: 8462960
+  timestamp: 1736088436984
 - conda: https://prefix.dev/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_2.conda
   sha256: da157b19bcd398b9804c5c52fc000fcb8ab0525bdb9c70f95beaa0bb42f85af1
   md5: 3bfed7e6228ebf2f7b9eaa47f1b4e2aa
@@ -1995,7 +2013,7 @@ packages:
 - pypi: .
   name: pint-array
   version: 0.0.1.dev0
-  sha256: f755911bc8a921cbb2e3867f4638c8fc32d2f9090b17c405eefd0019e5c5335e
+  sha256: 24493191fd5707853309652b03e9a153a4d9ace5f7f1b9c9ccb73d824f68d514
   requires_python: '>=3.10'
   editable: true
 - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
@@ -2137,6 +2155,19 @@ packages:
   - pkg:pypi/pytest-metadata?source=hash-mapping
   size: 14532
   timestamp: 1734146281190
+- conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
+  sha256: 610b1f994b7409cc131b5ecc838e515bf2c89eddcddb0b18a85dc6823eddc3d9
+  md5: c94aae4e1b32cddb4e6a3dedeee8092b
+  depends:
+  - attrs >=19.2.0
+  - pytest >=7.4
+  - python >=3.9
+  license: MIT
+  license_family: MIT
+  purls:
+  - pkg:pypi/pytest-subtests?source=hash-mapping
+  size: 17983
+  timestamp: 1733872677650
 - conda: https://prefix.dev/conda-forge/linux-64/python-3.10.16-he725a3c_1_cpython.conda
   build_number: 1
   sha256: 3f90a2d5062a73cd2dd8a0027718aee1db93f7975b9cfe529e2c9aeec2db262e
@@ -2627,9 +2658,9 @@ packages:
   purls: []
   size: 754247
   timestamp: 1731710681163
-- conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.0-pyhd8ed1ab_0.conda
-  sha256: 82776f74e90a296b79415361faa6b10f360755c1fb8e6d59ca68509e6fe7e115
-  md5: 1d601bc1d28b5ce6d112b90f4b9b8ede
+- conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
+  sha256: c8bde4547ddbd21ea89e483a7c65d8a5e442c0db494b0b977e389b75b9d03d62
+  md5: 680b1c287b10cefc8bda0530b217229f
   depends:
   - distlib >=0.3.7,<1
   - filelock >=3.12.2,<4
@@ -2639,8 +2670,8 @@ packages:
   license_family: MIT
   purls:
   - pkg:pypi/virtualenv?source=hash-mapping
-  size: 3350255
-  timestamp: 1732609542072
+  size: 3350367
+  timestamp: 1735929107438
 - conda: https://prefix.dev/conda-forge/win-64/vs2015_runtime-14.42.34433-hdffcdeb_23.conda
   sha256: 568ce8151eaae256f1cef752fc78651ad7a86ff05153cc7a4740b52ae6536118
   md5: 5c176975ca2b8366abad3c97b3cd1e83

From c5a3424b33151d0ffa7e70cd5955c48e41443312 Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Mon, 6 Jan 2025 12:42:11 +0000
Subject: [PATCH 28/49] fix xp-tests

---
 pixi.lock                  |  2 +-
 pyproject.toml             |  2 +-
 src/pint_array/__init__.py | 43 ++++++++++++++++++++++++++------------
 tests/test_array.py        | 37 +++++++++++++-------------------
 xp-tests-xfails.txt        |  2 ++
 5 files changed, 48 insertions(+), 38 deletions(-)

diff --git a/pixi.lock b/pixi.lock
index 96579da..523ac68 100644
--- a/pixi.lock
+++ b/pixi.lock
@@ -2013,7 +2013,7 @@ packages:
 - pypi: .
   name: pint-array
   version: 0.0.1.dev0
-  sha256: 24493191fd5707853309652b03e9a153a4d9ace5f7f1b9c9ccb73d824f68d514
+  sha256: 4a89db66462f8ea5ad75b3a9e4b4b623805532b36abed68b124c6e67a3022bfe
   requires_python: '>=3.10'
   editable: true
 - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
diff --git a/pyproject.toml b/pyproject.toml
index 91de1ce..e5e5a11 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -43,7 +43,7 @@ pytest = "*"
 pytest-subtests = "*"
 
 [tool.pixi.feature.tests.tasks]
-tests = "pytest"
+tests = "pytest tests"
 
 [tool.pixi.feature.xp-tests.dependencies]
 pytest = "*"
diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index c6f4fcb..8e03f93 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -15,7 +15,7 @@
 from typing import Generic
 
 from array_api_compat import size
-from pint import DimensionalityError, OffsetUnitCalculusError, Quantity
+from pint import DimensionalityError, Quantity
 from pint.facets.plain import MagnitudeT, PlainQuantity
 
 __version__ = "0.0.1.dev0"
@@ -493,9 +493,11 @@ def searchsorted(x1, x2, /, *, side="left", sorter=None):
     # ignore units of condition, convert x2 to units of x1
     def where(condition, x1, x2, /):
         if not getattr(condition, "_is_multiplicative", True):
-            raise ValueError(
-                "Invalid units of the condition: Boolean value of Quantity with offset unit is ambiguous."
+            msg = (
+                "Invalid units of the condition: "
+                "Boolean value of Quantity with offset unit is ambiguous."
             )
+            raise ValueError(msg)
 
         condition = asarray(condition)
         if hasattr(x1, "units") and hasattr(x2, "units"):
@@ -508,7 +510,6 @@ def where(condition, x1, x2, /):
             x1 = asarray(x1, units=x2.units)
             x2 = asarray(x2)
         units = x1.units
-        print(x2.m_as(units))
         magnitude = xp.where(condition.magnitude, x1.magnitude, x2.m_as(units))
         return ArrayUnitQuantity(magnitude, units)
 
@@ -730,16 +731,32 @@ def pow(x1, x2, /, *args, **kwargs):
 
         if not x2.units.dimensionless:
             raise DimensionalityError(x2.units, "dimensionless")
-        if x2.ndim > 0 and not xp.all(x2.magnitude == x2[0].magnitude):
-            raise DimensionalityError(
-                x2.units,
-                "dimensionless",
-                extra_msg="The exponent must be a scalar or an array of all the same value.",
-            )
-
-        units = x1.units**x2.magnitude
+        x2_magnitude = x2.magnitude
+        x2_magnitude_dtype = x2_magnitude.dtype
+        if xp.isdtype(x2_magnitude_dtype, "complex floating"):
+            as_scalar = complex
+        elif xp.isdtype(x2_magnitude_dtype, "real floating"):
+            as_scalar = float
+        elif xp.isdtype(x2_magnitude_dtype, "integral"):
+            as_scalar = int
+        else:
+            as_scalar = bool
+        if x2.ndim == 0:
+            units = x1.units ** as_scalar(x2_magnitude)
+        else:
+            x2_first_elem_magnitude = x2[(0,) * x2.ndim]
+            if not xp.all(x2_magnitude == x2_first_elem_magnitude):
+                extra_msg = (
+                    "The exponent must be a scalar or an array of all the same value."
+                )
+                raise DimensionalityError(
+                    x2.units,
+                    "dimensionless",
+                    extra_msg=extra_msg,
+                )
+            units = x1.units ** as_scalar(x2_first_elem_magnitude)
 
-        magnitude = xp.pow(x1.magnitude, x2.magnitude, *args, **kwargs)
+        magnitude = xp.pow(x1.magnitude, x2_magnitude, *args, **kwargs)
         return ArrayUnitQuantity(magnitude, units)
 
     mod.pow = pow
diff --git a/tests/test_array.py b/tests/test_array.py
index 040730c..5b2a214 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -6,28 +6,28 @@
 
 import numpy as np
 import pytest
-from pint import DimensionalityError, OffsetUnitCalculusError
-
-# from pint.compat import np
+from pint import DimensionalityError, OffsetUnitCalculusError, UnitRegistry
 from pint.testsuite import helpers
 
 import pint_array
 
 pnp = pint_array.pint_namespace(np)
-from pint import UnitRegistry
-
 ureg = UnitRegistry()
 
 <<<<<<< HEAD
 <<<<<<< HEAD
 =======
 
+<<<<<<< HEAD
 # @helpers.requires_numpy
 >>>>>>> 1ad9ca9 (style: pre-commit fixes)
 =======
 
 >>>>>>> 8498256 (style: pre-commit fixes)
 class TestNumpyMethods:
+=======
+class TestNumPyMethods:
+>>>>>>> 573558d (fix xp-tests)
     @classmethod
     def setup_class(cls):
         from pint import _DEFAULT_REGISTRY
@@ -67,10 +67,10 @@ def assertNDArrayEqual(self, actual, desired):
         assert not isinstance(desired, self.Q_)
 
 
-class TestNumpyArrayCreation(TestNumpyMethods):
+class TestNumPyArrayCreation(TestNumPyMethods):
     # https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html
 
-    @pytest.mark.xfail(reason="Scalar arguement issue ")
+    @pytest.mark.xfail(reason="Scalar argument issue ")
     def test_ones_like(self):
         self.assertNDArrayEqual(pnp.ones_like(self.q), np.array([[1, 1], [1, 1]]))
 
@@ -82,7 +82,7 @@ def test_empty_like(self):
         assert ret.shape == (2, 2)
         assert isinstance(ret.magnitude, np.ndarray)
 
-    @pytest.mark.xfail(reason="Scalar arguement issue ")
+    @pytest.mark.xfail(reason="Scalar argument issue ")
     def test_full_like(self):
         helpers.assert_quantity_equal(
             pnp.full_like(self.q, self.Q_(0, self.ureg.degC)),
@@ -91,13 +91,7 @@ def test_full_like(self):
         self.assertNDArrayEqual(pnp.full_like(self.q, 2), np.array([[2, 2], [2, 2]]))
 
 
-class TestNumpyArrayManipulation(TestNumpyMethods):
-    # TODO
-    # https://www.numpy.org/devdocs/reference/routines.array-manipulation.html
-    # copyto
-    # broadcast
-    # asarray	asanyarray	asmatrix	asfarray	asfortranarray	ascontiguousarray	asarray_chkfinite	asscalar	require
-
+class TestNumPyArrayManipulation(TestNumPyMethods):
     # Changing array shape
 
     def test_flatten(self):
@@ -194,12 +188,11 @@ def test_roll(self):
         )
 
 
-class TestNumpyMathematicalFunctions(TestNumpyMethods):
+class TestNumPyMathematicalFunctions(TestNumPyMethods):
     # https://www.numpy.org/devdocs/reference/routines.math.html
 
     def test_prod_numpy_func(self):
         axis = 0
-        where = [[True, False], [True, True]]
 
         helpers.assert_quantity_equal(pnp.prod(self.q), 24 * self.ureg.m**4)
         helpers.assert_quantity_equal(
@@ -278,7 +271,7 @@ def test_exponentiation_array_exp_2(self):
             op.ipow(arr_cp, q_cp)
 
 
-class TestNumpyUnclassified(TestNumpyMethods):
+class TestNumPyUnclassified(TestNumPyMethods):
     def test_repeat(self):
         helpers.assert_quantity_equal(
             pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
@@ -303,13 +296,13 @@ def test_nonzero_numpy_func(self):
     def test_any_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert pnp.any(q)
-        with pytest.raises(ValueError):
+        with pytest.raises(ValueError, match="offset unit is ambiguous"):
             pnp.any(self.q_temperature)
 
     def test_all_numpy_func(self):
         q = [0, 1] * self.ureg.m
         assert not pnp.all(q)
-        with pytest.raises(ValueError):
+        with pytest.raises(ValueError, match="offset unit is ambiguous"):
             pnp.all(self.q_temperature)
 
     def test_max_numpy_func(self):
@@ -438,11 +431,10 @@ def test_pickle(self, subtests):
     def test_equal(self):
         x = self.q.magnitude
         u = self.Q_(pnp.ones(x.shape))
-        true = pnp.ones_like(x, dtype=np.bool_)
         false = pnp.zeros_like(x, dtype=np.bool_)
 
         helpers.assert_quantity_equal(u, u)
-        helpers.assert_quantity_equal(u == u, u.magnitude == u.magnitude)
+        helpers.assert_quantity_equal(u, u.magnitude)
         helpers.assert_quantity_equal(u == 1, u.magnitude == 1)
 
         v = self.Q_(pnp.zeros(x.shape), "m")
@@ -452,7 +444,6 @@ def test_equal(self):
             self.Q_(pnp.zeros_like(x), "m") == self.Q_(pnp.zeros_like(x), "s"),
             false,
         )
-        self.assertNDArrayEqual(v == v, true)
         self.assertNDArrayEqual(v == w, false)
         self.assertNDArrayEqual(v == w.to("mm"), false)
         self.assertNDArrayEqual(u == v, false)
diff --git a/xp-tests-xfails.txt b/xp-tests-xfails.txt
index cc659de..6369ae4 100644
--- a/xp-tests-xfails.txt
+++ b/xp-tests-xfails.txt
@@ -38,3 +38,5 @@ array_api_tests/test_has_names.py::test_has_names[linalg-vecdot]
 array_api_tests/test_has_names.py::test_has_names[linalg-vector_norm]
 # flaky on macos
 array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt
+# `pow` with array x2 is only defined when all elements of x2 are equal
+array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)]

From 54038d5bc76e18d3a64d03ba51e4769569bfa74c Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Tue, 7 Jan 2025 23:35:51 +0000
Subject: [PATCH 29/49] np -> xp

---
 tests/test_array.py | 199 +++++++++++++++++++++++---------------------
 1 file changed, 102 insertions(+), 97 deletions(-)

diff --git a/tests/test_array.py b/tests/test_array.py
index 5b2a214..d153916 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -4,6 +4,7 @@
 import operator as op
 import pickle
 
+import array_api_strict as xp
 import numpy as np
 import pytest
 from pint import DimensionalityError, OffsetUnitCalculusError, UnitRegistry
@@ -11,7 +12,7 @@
 
 import pint_array
 
-pnp = pint_array.pint_namespace(np)
+pxp = pint_array.pint_namespace(xp)
 ureg = UnitRegistry()
 
 <<<<<<< HEAD
@@ -46,15 +47,15 @@ def q(self):
 
     @property
     def q_scalar(self):
-        return np.array(5) * self.ureg.m
+        return pxp.asarray(5) * self.ureg.m
 
     @property
     def q_nan(self):
-        return [[1, 2], [3, pnp.nan]] * self.ureg.m
+        return [[1, 2], [3, pxp.nan]] * self.ureg.m
 
     @property
     def q_zero_or_nan(self):
-        return [[0, 0], [0, pnp.nan]] * self.ureg.m
+        return [[0, 0], [0, pxp.nan]] * self.ureg.m
 
     @property
     def q_temperature(self):
@@ -72,23 +73,23 @@ class TestNumPyArrayCreation(TestNumPyMethods):
 
     @pytest.mark.xfail(reason="Scalar argument issue ")
     def test_ones_like(self):
-        self.assertNDArrayEqual(pnp.ones_like(self.q), np.array([[1, 1], [1, 1]]))
+        self.assertNDArrayEqual(pxp.ones_like(self.q), pxp.asarray([[1, 1], [1, 1]]))
 
     def test_zeros_like(self):
-        self.assertNDArrayEqual(pnp.zeros_like(self.q), np.array([[0, 0], [0, 0]]))
+        self.assertNDArrayEqual(pxp.zeros_like(self.q), pxp.asarray([[0, 0], [0, 0]]))
 
     def test_empty_like(self):
-        ret = pnp.empty_like(self.q)
+        ret = pxp.empty_like(self.q)
         assert ret.shape == (2, 2)
-        assert isinstance(ret.magnitude, np.ndarray)
+        assert ret.magnitude.__array_namespace__() is xp
 
     @pytest.mark.xfail(reason="Scalar argument issue ")
     def test_full_like(self):
         helpers.assert_quantity_equal(
-            pnp.full_like(self.q, self.Q_(0, self.ureg.degC)),
+            pxp.full_like(self.q, self.Q_(0, self.ureg.degC)),
             self.Q_([[0, 0], [0, 0]], self.ureg.degC),
         )
-        self.assertNDArrayEqual(pnp.full_like(self.q, 2), np.array([[2, 2], [2, 2]]))
+        self.assertNDArrayEqual(pxp.full_like(self.q, 2), pxp.asarray([[2, 2], [2, 2]]))
 
 
 class TestNumPyArrayManipulation(TestNumPyMethods):
@@ -110,43 +111,43 @@ def test_reshape(self):
 
     def test_moveaxis(self):
         helpers.assert_quantity_equal(
-            pnp.moveaxis(self.q, 1, 0), np.array([[1, 2], [3, 4]]).T * self.ureg.m
+            pxp.moveaxis(self.q, 1, 0), pxp.asarray([[1, 2], [3, 4]]).T * self.ureg.m
         )
 
     def test_transpose(self):
         helpers.assert_quantity_equal(
-            pnp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
+            pxp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
         )
 
     def test_flip_numpy_func(self):
         helpers.assert_quantity_equal(
-            pnp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
+            pxp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
         )
 
     # Changing number of dimensions
 
     def test_broadcast_to(self):
         helpers.assert_quantity_equal(
-            pnp.broadcast_to(self.q[:, 1], (2, 2)),
-            np.array([[2, 4], [2, 4]]) * self.ureg.m,
+            pxp.broadcast_to(self.q[:, 1], (2, 2)),
+            pxp.asarray([[2, 4], [2, 4]]) * self.ureg.m,
         )
 
     def test_expand_dims(self):
         helpers.assert_quantity_equal(
-            pnp.expand_dims(self.q, 0), np.array([[[1, 2], [3, 4]]]) * self.ureg.m
+            pxp.expand_dims(self.q, 0), pxp.asarray([[[1, 2], [3, 4]]]) * self.ureg.m
         )
 
     def test_squeeze(self):
-        helpers.assert_quantity_equal(pnp.squeeze(self.q), self.q)
+        helpers.assert_quantity_equal(pxp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
-            pnp.squeeze(self.q.reshape([1, 4])), [1, 2, 3, 4] * self.ureg.m
+            pxp.squeeze(self.q.reshape([1, 4])), [1, 2, 3, 4] * self.ureg.m
         )
 
     # Changing number of dimensions
     # Joining arrays
 
     def test_concat_stack(self, subtests):
-        for func in (pnp.concat, pnp.stack):
+        for func in (pxp.concat, pxp.stack):
             with subtests.test(func=func):
                 helpers.assert_quantity_equal(
                     func([self.q] * 2), self.Q_(func([self.q.m] * 2), self.ureg.m)
@@ -164,8 +165,10 @@ def test_concat_stack(self, subtests):
                     func([nz.m, self.q])
 
     def test_astype(self):
-        actual = self.q.astype(pnp.float32)
-        expected = self.Q_(np.array([[1.0, 2.0], [3.0, 4.0]], dtype=pnp.float32), "m")
+        actual = self.q.astype(pxp.float32)
+        expected = self.Q_(
+            pxp.asarray([[1.0, 2.0], [3.0, 4.0]], dtype=pxp.float32), "m"
+        )
         helpers.assert_quantity_equal(actual, expected)
         assert actual.m.dtype == expected.m.dtype
 
@@ -173,18 +176,18 @@ def test_item(self):
         helpers.assert_quantity_equal(self.Q_([[0]], "m").item(), 0 * self.ureg.m)
 
     def test_broadcast_arrays(self):
-        x = self.Q_(np.array([[1, 2, 3]]), "m")
-        y = self.Q_(np.array([[4], [5]]), "nm")
-        result = pnp.broadcast_arrays(x, y)
+        x = self.Q_(pxp.asarray([[1, 2, 3]]), "m")
+        y = self.Q_(pxp.asarray([[4], [5]]), "nm")
+        result = pxp.broadcast_arrays(x, y)
         expected = (
-            self.Q_(np.array([[1, 2, 3], [1, 2, 3]]), "m"),
-            self.Q_(np.array([[4, 4, 4], [5, 5, 5]]), "nm"),
+            self.Q_(pxp.asarray([[1, 2, 3], [1, 2, 3]]), "m"),
+            self.Q_(pxp.asarray([[4, 4, 4], [5, 5, 5]]), "nm"),
         )
         helpers.assert_quantity_equal(result, expected)
 
     def test_roll(self):
         helpers.assert_quantity_equal(
-            pnp.roll(self.q, 1), [[4, 1], [2, 3]] * self.ureg.m
+            pxp.roll(self.q, 1), [[4, 1], [2, 3]] * self.ureg.m
         )
 
 
@@ -194,19 +197,19 @@ class TestNumPyMathematicalFunctions(TestNumPyMethods):
     def test_prod_numpy_func(self):
         axis = 0
 
-        helpers.assert_quantity_equal(pnp.prod(self.q), 24 * self.ureg.m**4)
+        helpers.assert_quantity_equal(pxp.prod(self.q), 24 * self.ureg.m**4)
         helpers.assert_quantity_equal(
-            pnp.prod(self.q, axis=axis), [3, 8] * self.ureg.m**2
+            pxp.prod(self.q, axis=axis), [3, 8] * self.ureg.m**2
         )
 
     def test_sum_numpy_func(self):
-        helpers.assert_quantity_equal(pnp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
+        helpers.assert_quantity_equal(pxp.sum(self.q, axis=0), [4, 6] * self.ureg.m)
         with pytest.raises(OffsetUnitCalculusError):
-            pnp.sum(self.q_temperature)
+            pxp.sum(self.q_temperature)
 
     # Arithmetic operations
     def test_addition_with_scalar(self):
-        a = np.array([0, 1, 2])
+        a = pxp.asarray([0, 1, 2])
         b = 10.0 * self.ureg("gram/kilogram")
         helpers.assert_quantity_almost_equal(
             a + b, self.Q_([0.01, 1.01, 2.01], self.ureg.dimensionless)
@@ -216,7 +219,7 @@ def test_addition_with_scalar(self):
         )
 
     def test_addition_with_incompatible_scalar(self):
-        a = np.array([0, 1, 2])
+        a = pxp.asarray([0, 1, 2])
         b = 1.0 * self.ureg.m
         with pytest.raises(DimensionalityError):
             op.add(a, b)
@@ -224,10 +227,10 @@ def test_addition_with_incompatible_scalar(self):
             op.add(b, a)
 
     def test_power(self):
-        arr = np.array(range(3), dtype=float)
+        arr = pxp.asarray(range(3), dtype=float)
         q = self.Q_(arr, "meter")
 
-        for op_ in [pnp.pow]:
+        for op_ in [pxp.pow]:
             q_cp = copy.copy(q)
             with pytest.raises(DimensionalityError):
                 op_(2.0, q_cp)
@@ -241,20 +244,20 @@ def test_power(self):
                 op_(q_cp, q2_cp)
 
         helpers.assert_quantity_equal(
-            pnp.pow(self.q, self.Q_(2)), self.Q_([[1, 4], [9, 16]], "m**2")
+            pxp.pow(self.q, self.Q_(2)), self.Q_([[1, 4], [9, 16]], "m**2")
         )
         helpers.assert_quantity_equal(
             self.q ** self.Q_(2), self.Q_([[1, 4], [9, 16]], "m**2")
         )
-        self.assertNDArrayEqual(arr ** self.Q_(2), np.array([0, 1, 4]))
+        self.assertNDArrayEqual(arr ** self.Q_(2), pxp.asarray([0, 1, 4]))
 
     def test_sqrt(self):
         q = self.Q_(100, "m**2")
-        helpers.assert_quantity_equal(pnp.sqrt(q), self.Q_(10, "m"))
+        helpers.assert_quantity_equal(pxp.sqrt(q), self.Q_(10, "m"))
 
     @pytest.mark.xfail
     def test_exponentiation_array_exp_2(self):
-        arr = np.array(range(3), dtype=float)
+        arr = pxp.asarray(range(3), dtype=float)
         # q = self.Q_(copy.copy(arr), None)
         q = self.Q_(copy.copy(arr), "meter")
         arr_cp = copy.copy(arr)
@@ -274,94 +277,96 @@ def test_exponentiation_array_exp_2(self):
 class TestNumPyUnclassified(TestNumPyMethods):
     def test_repeat(self):
         helpers.assert_quantity_equal(
-            pnp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
+            pxp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
         )
 
     def test_sort_numpy_func(self):
         q = [4, 5, 2, 3, 1, 6] * self.ureg.m
-        helpers.assert_quantity_equal(pnp.sort(q), [1, 2, 3, 4, 5, 6] * self.ureg.m)
+        helpers.assert_quantity_equal(pxp.sort(q), [1, 2, 3, 4, 5, 6] * self.ureg.m)
 
     def test_argsort_numpy_func(self):
-        self.assertNDArrayEqual(pnp.argsort(self.q, axis=0), np.array([[0, 0], [1, 1]]))
+        self.assertNDArrayEqual(
+            pxp.argsort(self.q, axis=0), pxp.asarray([[0, 0], [1, 1]])
+        )
 
     def test_searchsorted_numpy_func(self):
         """Test searchsorted as numpy function."""
         q = self.q.flatten()
-        self.assertNDArrayEqual(pnp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
+        self.assertNDArrayEqual(pxp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
 
     def test_nonzero_numpy_func(self):
         q = [1, 0, 5, 6, 0, 9] * self.ureg.m
-        self.assertNDArrayEqual(pnp.nonzero(q)[0], [0, 2, 3, 5])
+        self.assertNDArrayEqual(pxp.nonzero(q)[0], [0, 2, 3, 5])
 
     def test_any_numpy_func(self):
         q = [0, 1] * self.ureg.m
-        assert pnp.any(q)
+        assert pxp.any(q)
         with pytest.raises(ValueError, match="offset unit is ambiguous"):
-            pnp.any(self.q_temperature)
+            pxp.any(self.q_temperature)
 
     def test_all_numpy_func(self):
         q = [0, 1] * self.ureg.m
-        assert not pnp.all(q)
+        assert not pxp.all(q)
         with pytest.raises(ValueError, match="offset unit is ambiguous"):
-            pnp.all(self.q_temperature)
+            pxp.all(self.q_temperature)
 
     def test_max_numpy_func(self):
-        assert pnp.max(self.q) == 4 * self.ureg.m
+        assert pxp.max(self.q) == 4 * self.ureg.m
 
     def test_max_with_axis_arg(self):
-        helpers.assert_quantity_equal(pnp.max(self.q, axis=1), [2, 4] * self.ureg.m)
+        helpers.assert_quantity_equal(pxp.max(self.q, axis=1), [2, 4] * self.ureg.m)
 
     def test_argmax_numpy_func(self):
-        self.assertNDArrayEqual(pnp.argmax(self.q, axis=0), np.array([1, 1]))
+        self.assertNDArrayEqual(pxp.argmax(self.q, axis=0), pxp.asarray([1, 1]))
 
     def test_maximum(self):
         helpers.assert_quantity_equal(
-            pnp.maximum(self.q, self.Q_([0, 5], "m")), self.Q_([[1, 5], [3, 5]], "m")
+            pxp.maximum(self.q, self.Q_([0, 5], "m")), self.Q_([[1, 5], [3, 5]], "m")
         )
 
     def test_min_numpy_func(self):
-        assert pnp.min(self.q) == 1 * self.ureg.m
+        assert pxp.min(self.q) == 1 * self.ureg.m
 
     def test_min_with_axis_arg(self):
-        helpers.assert_quantity_equal(pnp.min(self.q, axis=1), [1, 3] * self.ureg.m)
+        helpers.assert_quantity_equal(pxp.min(self.q, axis=1), [1, 3] * self.ureg.m)
 
     def test_argmin_numpy_func(self):
-        self.assertNDArrayEqual(pnp.argmin(self.q, axis=0), np.array([0, 0]))
+        self.assertNDArrayEqual(pxp.argmin(self.q, axis=0), pxp.asarray([0, 0]))
 
     def test_minimum(self):
         helpers.assert_quantity_equal(
-            pnp.minimum(self.q, self.Q_([0, 5], "m")), self.Q_([[0, 2], [0, 4]], "m")
+            pxp.minimum(self.q, self.Q_([0, 5], "m")), self.Q_([[0, 2], [0, 4]], "m")
         )
 
     def test_clip_numpy_func(self):
         helpers.assert_quantity_equal(
-            pnp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
+            pxp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
         )
 
     def test_round_numpy_func(self):
         helpers.assert_quantity_equal(
-            pnp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
+            pxp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
         )
 
     def test_cumulative_sum(self):
         helpers.assert_quantity_equal(
-            pnp.cumulative_sum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
+            pxp.cumulative_sum(self.q, axis=0), [[1, 2], [4, 6]] * self.ureg.m
         )
 
     def test_mean_numpy_func(self):
-        assert pnp.mean(self.q) == 2.5 * self.ureg.m
-        assert pnp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
+        assert pxp.mean(self.q) == 2.5 * self.ureg.m
+        assert pxp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
 
     def test_var_numpy_func(self):
-        assert pnp.var(self.q) == 1.25 * self.ureg.m**2
-        assert pnp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
+        assert pxp.var(self.q) == 1.25 * self.ureg.m**2
+        assert pxp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
 
     def test_std_numpy_func(self):
         helpers.assert_quantity_almost_equal(
-            pnp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
+            pxp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
         )
         helpers.assert_quantity_almost_equal(
-            pnp.std(self.q_temperature), 1.11803 * self.ureg.delta_degC, rtol=1e-5
+            pxp.std(self.q_temperature), 1.11803 * self.ureg.delta_degC, rtol=1e-5
         )
 
     def test_conj(self):
@@ -384,7 +389,7 @@ def test_setitem(self):
         with pytest.raises(DimensionalityError):
             self.q[0] = 1
         with pytest.raises(DimensionalityError):
-            self.q[0] = np.ndarray([1, 2])
+            self.q[0] = pxp.asarray([1, 2])
         with pytest.raises(DimensionalityError):
             self.q[0] = 1 * self.ureg.J
 
@@ -403,9 +408,9 @@ def test_setitem(self):
         # check and see that dimensionless numbers work correctly
         q = [0, 1, 2, 3] * self.ureg.dimensionless
         q[0] = 1
-        helpers.assert_quantity_equal(q, pnp.asarray([1, 1, 2, 3]))
+        helpers.assert_quantity_equal(q, pxp.asarray([1, 1, 2, 3]))
         q[0] = self.ureg.m / self.ureg.mm
-        helpers.assert_quantity_equal(q, pnp.asarray([1000, 1, 2, 3]))
+        helpers.assert_quantity_equal(q, pxp.asarray([1000, 1, 2, 3]))
 
         q = [0.0, 1.0, 2.0, 3.0] * self.ureg.m / self.ureg.mm
         q[0] = 1.0
@@ -414,7 +419,7 @@ def test_setitem(self):
     def test_reversible_op(self):
         """ """
         x = self.q.magnitude
-        u = self.Q_(pnp.ones(x.shape))
+        u = self.Q_(pxp.ones(x.shape))
         helpers.assert_quantity_equal(x / self.q, u * x / self.q)
         helpers.assert_quantity_equal(x * self.q, u * x * self.q)
         helpers.assert_quantity_equal(x + u, u + x)
@@ -430,18 +435,18 @@ def test_pickle(self, subtests):
 
     def test_equal(self):
         x = self.q.magnitude
-        u = self.Q_(pnp.ones(x.shape))
-        false = pnp.zeros_like(x, dtype=np.bool_)
+        u = self.Q_(pxp.ones(x.shape))
+        false = pxp.zeros_like(x, dtype=pxp.bool)
 
         helpers.assert_quantity_equal(u, u)
         helpers.assert_quantity_equal(u, u.magnitude)
         helpers.assert_quantity_equal(u == 1, u.magnitude == 1)
 
-        v = self.Q_(pnp.zeros(x.shape), "m")
-        w = self.Q_(pnp.ones(x.shape), "m")
+        v = self.Q_(pxp.zeros(x.shape), "m")
+        w = self.Q_(pxp.ones(x.shape), "m")
         self.assertNDArrayEqual(v == 1, false)
         self.assertNDArrayEqual(
-            self.Q_(pnp.zeros_like(x), "m") == self.Q_(pnp.zeros_like(x), "s"),
+            self.Q_(pxp.zeros_like(x), "m") == self.Q_(pxp.zeros_like(x), "s"),
             false,
         )
         self.assertNDArrayEqual(v == w, false)
@@ -449,80 +454,80 @@ def test_equal(self):
         self.assertNDArrayEqual(u == v, false)
 
     def test_dtype(self):
-        u = self.Q_(pnp.arange(12, dtype="uint32"))
+        u = self.Q_(pxp.arange(12, dtype="uint32"))
 
         assert u.dtype == "uint32"
 
     def test_shape_numpy_func(self):
-        assert pnp.asarray(self.q).shape == (2, 2)
+        assert pxp.asarray(self.q).shape == (2, 2)
 
     def test_ndim_numpy_func(self):
-        assert pnp.asarray(self.q).ndim == 2
+        assert pxp.asarray(self.q).ndim == 2
 
     def test_meshgrid_numpy_func(self):
         x = [1, 2] * self.ureg.m
         y = [0, 50, 100] * self.ureg.mm
-        xx, yy = pnp.meshgrid(x, y)
+        xx, yy = pxp.meshgrid(x, y)
         helpers.assert_quantity_equal(xx, [[1, 2], [1, 2], [1, 2]] * self.ureg.m)
         helpers.assert_quantity_equal(yy, [[0, 0], [50, 50], [100, 100]] * self.ureg.mm)
 
     def test_comparisons(self):
         self.assertNDArrayEqual(
-            self.q > 2 * self.ureg.m, np.array([[False, False], [True, True]])
+            self.q > 2 * self.ureg.m, pxp.asarray([[False, False], [True, True]])
         )
         self.assertNDArrayEqual(
-            self.q < 2 * self.ureg.m, np.array([[True, False], [False, False]])
+            self.q < 2 * self.ureg.m, pxp.asarray([[True, False], [False, False]])
         )
 
     def test_where(self):
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 2 * self.ureg.m, self.q, 20 * self.ureg.m),
+            pxp.where(self.q >= 2 * self.ureg.m, self.q, 20 * self.ureg.m),
             [[20, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 2 * self.ureg.m, self.q, 0),
+            pxp.where(self.q >= 2 * self.ureg.m, self.q, 0),
             [[0, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 2 * self.ureg.m, self.q, pnp.nan),
-            [[pnp.nan, 2], [3, 4]] * self.ureg.m,
+            pxp.where(self.q >= 2 * self.ureg.m, self.q, pxp.nan),
+            [[pxp.nan, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 3 * self.ureg.m, 0, self.q),
+            pxp.where(self.q >= 3 * self.ureg.m, 0, self.q),
             [[1, 2], [0, 0]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 3 * self.ureg.m, pnp.nan, self.q),
-            [[1, 2], [pnp.nan, pnp.nan]] * self.ureg.m,
+            pxp.where(self.q >= 3 * self.ureg.m, pxp.nan, self.q),
+            [[1, 2], [pxp.nan, pxp.nan]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 2 * self.ureg.m, self.q, np.array(pnp.nan)),
-            [[pnp.nan, 2], [3, 4]] * self.ureg.m,
+            pxp.where(self.q >= 2 * self.ureg.m, self.q, pxp.asarray(pxp.nan)),
+            [[pxp.nan, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pnp.where(self.q >= 3 * self.ureg.m, np.array(pnp.nan), self.q),
-            [[1, 2], [pnp.nan, pnp.nan]] * self.ureg.m,
+            pxp.where(self.q >= 3 * self.ureg.m, pxp.asarray(pxp.nan), self.q),
+            [[1, 2], [pxp.nan, pxp.nan]] * self.ureg.m,
         )
         with pytest.raises(DimensionalityError):
-            pnp.where(
+            pxp.where(
                 self.q < 2 * self.ureg.m,
                 self.q,
                 0 * self.ureg.J,
             )
 
         helpers.assert_quantity_equal(
-            pnp.where([-1, 0, 1] * self.ureg.m, [1, 2, 1] * self.ureg.s, pnp.nan),
-            [1, pnp.nan, 1] * self.ureg.s,
+            pxp.where([-1, 0, 1] * self.ureg.m, [1, 2, 1] * self.ureg.s, pxp.nan),
+            [1, pxp.nan, 1] * self.ureg.s,
         )
         with pytest.raises(
             ValueError,
             match=".*Boolean value of Quantity with offset unit is ambiguous",
         ):
-            pnp.where(
-                self.ureg.Quantity([-1, 0, 1], "degC"), [1, 2, 1] * self.ureg.s, pnp.nan
+            pxp.where(
+                self.ureg.Quantity([-1, 0, 1], "degC"), [1, 2, 1] * self.ureg.s, pxp.nan
             )
 
     def test_tile(self):
         helpers.assert_quantity_equal(
-            pnp.tile(self.q, 2), np.array([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m
+            pxp.tile(self.q, 2), pxp.asarray([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m
         )

From 4f9d05c30ce7eb02ca0f7bbf9212e3b856be51f1 Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Tue, 7 Jan 2025 23:37:27 +0000
Subject: [PATCH 30/49] remove pickle test

---
 tests/test_array.py | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/tests/test_array.py b/tests/test_array.py
index d153916..1408881 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -2,7 +2,6 @@
 
 import copy
 import operator as op
-import pickle
 
 import array_api_strict as xp
 import numpy as np
@@ -425,14 +424,6 @@ def test_reversible_op(self):
         helpers.assert_quantity_equal(x + u, u + x)
         helpers.assert_quantity_equal(x - u, -(u - x))
 
-    def test_pickle(self, subtests):
-        for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
-            with subtests.test(protocol):
-                q1 = [10, 20] * self.ureg.m
-                q2 = pickle.loads(pickle.dumps(q1, protocol))
-                self.assertNDArrayEqual(q1.magnitude, q2.magnitude)
-                assert q1.units == q2.units
-
     def test_equal(self):
         x = self.q.magnitude
         u = self.Q_(pxp.ones(x.shape))

From 2242bf33a86c27c59e062af2de5cd3151b16116d Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Tue, 7 Jan 2025 23:46:23 +0000
Subject: [PATCH 31/49] some tweaks

---
 src/pint_array/__init__.py |  2 ++
 tests/test_array.py        | 21 ++++++++++-----------
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 8e03f93..eb440db 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -946,4 +946,6 @@ def clip(x, /, min=None, max=None):
             with contextlib.suppress(AttributeError, TypeError):
                 mod_attr.__name__ = xp_attr.__name__
 
+    mod.ArrayUnitQuantity = ArrayUnitQuantity
+
     return mod
diff --git a/tests/test_array.py b/tests/test_array.py
index 1408881..83ae407 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -6,13 +6,12 @@
 import array_api_strict as xp
 import numpy as np
 import pytest
-from pint import DimensionalityError, OffsetUnitCalculusError, UnitRegistry
+from pint import DimensionalityError, OffsetUnitCalculusError
 from pint.testsuite import helpers
 
 import pint_array
 
 pxp = pint_array.pint_namespace(xp)
-ureg = UnitRegistry()
 
 <<<<<<< HEAD
 <<<<<<< HEAD
@@ -33,7 +32,7 @@ def setup_class(cls):
         from pint import _DEFAULT_REGISTRY
 
         cls.ureg = _DEFAULT_REGISTRY
-        cls.Q_ = cls.ureg.Quantity
+        cls.Q_ = pxp.ArrayUnitQuantity
 
     @classmethod
     def teardown_class(cls):
@@ -42,23 +41,23 @@ def teardown_class(cls):
 
     @property
     def q(self):
-        return [[1, 2], [3, 4]] * self.ureg.m
+        return pxp.asarray([[1, 2], [3, 4]], units=self.ureg.m)
 
     @property
     def q_scalar(self):
-        return pxp.asarray(5) * self.ureg.m
+        return pxp.asarray(5, units=self.ureg.m)
 
     @property
     def q_nan(self):
-        return [[1, 2], [3, pxp.nan]] * self.ureg.m
+        return pxp.asarray([[1, 2], [3, pxp.nan]], units=self.ureg.m)
 
     @property
     def q_zero_or_nan(self):
-        return [[0, 0], [0, pxp.nan]] * self.ureg.m
+        return pxp.asarray([[0, 0], [0, pxp.nan]], units=self.ureg.m)
 
     @property
     def q_temperature(self):
-        return self.Q_([[1, 2], [3, 4]], self.ureg.degC)
+        return pxp.asarray([[1, 2], [3, 4]], self.ureg.degC)
 
     def assertNDArrayEqual(self, actual, desired):
         # Assert that the given arrays are equal, and are not Quantities
@@ -115,12 +114,12 @@ def test_moveaxis(self):
 
     def test_transpose(self):
         helpers.assert_quantity_equal(
-            pxp.matrix_transpose(self.q), [[1, 3], [2, 4]] * self.ureg.m
+            pxp.matrix_transpose(self.q), pxp.asarray([[1, 3], [2, 4]]) * self.ureg.m
         )
 
     def test_flip_numpy_func(self):
         helpers.assert_quantity_equal(
-            pxp.flip(self.q, axis=0), [[3, 4], [1, 2]] * self.ureg.m
+            pxp.flip(self.q, axis=0), pxp.asarray([[3, 4], [1, 2]]) * self.ureg.m
         )
 
     # Changing number of dimensions
@@ -139,7 +138,7 @@ def test_expand_dims(self):
     def test_squeeze(self):
         helpers.assert_quantity_equal(pxp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
-            pxp.squeeze(self.q.reshape([1, 4])), [1, 2, 3, 4] * self.ureg.m
+            pxp.squeeze(self.q.reshape([1, 4])), pxp.asarray([1, 2, 3, 4]) * self.ureg.m
         )
 
     # Changing number of dimensions

From e2050efa30bf21a7eed504f28a5a579faae0ca0c Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sat, 11 Jan 2025 18:11:28 +0000
Subject: [PATCH 32/49] pass some tests

---
 src/pint_array/__init__.py |   2 +
 tests/test_array.py        | 114 ++++++++++++++++++++-----------------
 2 files changed, 63 insertions(+), 53 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index eb440db..609891e 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -115,6 +115,8 @@ def __mul__(self, other):
             else:
                 magnitude = self._call_super_method("__mul__", other)
                 units = self.units
+            if magnitude is NotImplemented:
+                return NotImplemented
             return ArrayUnitQuantity(magnitude, units)
 
         def __gt__(self, other):
diff --git a/tests/test_array.py b/tests/test_array.py
index 83ae407..3c688b9 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -57,7 +57,7 @@ def q_zero_or_nan(self):
 
     @property
     def q_temperature(self):
-        return pxp.asarray([[1, 2], [3, 4]], self.ureg.degC)
+        return pxp.asarray([[1, 2], [3, 4]], units = self.ureg.degC)
 
     def assertNDArrayEqual(self, actual, desired):
         # Assert that the given arrays are equal, and are not Quantities
@@ -73,6 +73,7 @@ class TestNumPyArrayCreation(TestNumPyMethods):
     def test_ones_like(self):
         self.assertNDArrayEqual(pxp.ones_like(self.q), pxp.asarray([[1, 1], [1, 1]]))
 
+    @pytest.mark.xfail(reason="should this be using NDArrayEqual?")
     def test_zeros_like(self):
         self.assertNDArrayEqual(pxp.zeros_like(self.q), pxp.asarray([[0, 0], [0, 0]]))
 
@@ -93,16 +94,9 @@ def test_full_like(self):
 class TestNumPyArrayManipulation(TestNumPyMethods):
     # Changing array shape
 
-    def test_flatten(self):
-        helpers.assert_quantity_equal(self.q.flatten(), [1, 2, 3, 4] * self.ureg.m)
-
-    def test_flat(self):
-        for q, v in zip(self.q.flat, [1, 2, 3, 4], strict=False):
-            assert q == v * self.ureg.m
-
     def test_reshape(self):
         helpers.assert_quantity_equal(
-            self.q.reshape([1, 4]), [[1, 2, 3, 4]] * self.ureg.m
+            pxp.reshape(self.q, [1, 4]), pxp.asarray([[1, 2, 3, 4]] ) * self.ureg.m
         )
 
     # Transpose-like operations
@@ -132,13 +126,13 @@ def test_broadcast_to(self):
 
     def test_expand_dims(self):
         helpers.assert_quantity_equal(
-            pxp.expand_dims(self.q, 0), pxp.asarray([[[1, 2], [3, 4]]]) * self.ureg.m
+            pxp.expand_dims(self.q, axis=0), pxp.asarray([[[1, 2], [3, 4]]]) * self.ureg.m
         )
 
     def test_squeeze(self):
-        helpers.assert_quantity_equal(pxp.squeeze(self.q), self.q)
         helpers.assert_quantity_equal(
-            pxp.squeeze(self.q.reshape([1, 4])), pxp.asarray([1, 2, 3, 4]) * self.ureg.m
+            pxp.squeeze(pxp.asarray([[[0], [1], [2]]]) *self.ureg.m, axis=0),
+            pxp.asarray([0,1,2]) * self.ureg.m
         )
 
     # Changing number of dimensions
@@ -148,7 +142,7 @@ def test_concat_stack(self, subtests):
         for func in (pxp.concat, pxp.stack):
             with subtests.test(func=func):
                 helpers.assert_quantity_equal(
-                    func([self.q] * 2), self.Q_(func([self.q.m] * 2), self.ureg.m)
+                    func([self.q] * 2), pxp.asarray(func([self.q.m] * 2), units = "m")
                 )
                 # One or more of the args is a bare array full of zeros or NaNs
                 # helpers.assert_quantity_equal(
@@ -163,10 +157,9 @@ def test_concat_stack(self, subtests):
                     func([nz.m, self.q])
 
     def test_astype(self):
-        actual = self.q.astype(pxp.float32)
-        expected = self.Q_(
-            pxp.asarray([[1.0, 2.0], [3.0, 4.0]], dtype=pxp.float32), "m"
-        )
+        dtype=pxp.float32
+        actual = pxp.astype(self.q, dtype)
+        expected = pxp.asarray([[1.0, 2.0], [3.0, 4.0]], dtype=dtype, units = "m")
         helpers.assert_quantity_equal(actual, expected)
         assert actual.m.dtype == expected.m.dtype
 
@@ -174,12 +167,12 @@ def test_item(self):
         helpers.assert_quantity_equal(self.Q_([[0]], "m").item(), 0 * self.ureg.m)
 
     def test_broadcast_arrays(self):
-        x = self.Q_(pxp.asarray([[1, 2, 3]]), "m")
-        y = self.Q_(pxp.asarray([[4], [5]]), "nm")
+        x = pxp.asarray([[1, 2, 3]], units= "m")
+        y = pxp.asarray([[4], [5]], units= "nm")
         result = pxp.broadcast_arrays(x, y)
         expected = (
-            self.Q_(pxp.asarray([[1, 2, 3], [1, 2, 3]]), "m"),
-            self.Q_(pxp.asarray([[4, 4, 4], [5, 5, 5]]), "nm"),
+            pxp.asarray([[1, 2, 3], [1, 2, 3]], units= "m"),
+            pxp.asarray([[4, 4, 4], [5, 5, 5]], units= "nm")
         )
         helpers.assert_quantity_equal(result, expected)
 
@@ -207,13 +200,13 @@ def test_sum_numpy_func(self):
 
     # Arithmetic operations
     def test_addition_with_scalar(self):
-        a = pxp.asarray([0, 1, 2])
+        a = pxp.asarray([0, 1, 2], dtype = pxp.float32)
         b = 10.0 * self.ureg("gram/kilogram")
         helpers.assert_quantity_almost_equal(
-            a + b, self.Q_([0.01, 1.01, 2.01], self.ureg.dimensionless)
+            a + b, pxp.asarray([0.01, 1.01, 2.01], units = "")
         )
         helpers.assert_quantity_almost_equal(
-            b + a, self.Q_([0.01, 1.01, 2.01], self.ureg.dimensionless)
+            b + a, pxp.asarray([0.01, 1.01, 2.01], units = "")
         )
 
     def test_addition_with_incompatible_scalar(self):
@@ -225,7 +218,7 @@ def test_addition_with_incompatible_scalar(self):
             op.add(b, a)
 
     def test_power(self):
-        arr = pxp.asarray(range(3), dtype=float)
+        arr = pxp.asarray(range(3), dtype=pxp.float32)
         q = self.Q_(arr, "meter")
 
         for op_ in [pxp.pow]:
@@ -250,8 +243,8 @@ def test_power(self):
         self.assertNDArrayEqual(arr ** self.Q_(2), pxp.asarray([0, 1, 4]))
 
     def test_sqrt(self):
-        q = self.Q_(100, "m**2")
-        helpers.assert_quantity_equal(pxp.sqrt(q), self.Q_(10, "m"))
+        q = self.Q_(100.0, "m**2")
+        helpers.assert_quantity_equal(pxp.sqrt(q), self.Q_(10.0, "m"))
 
     @pytest.mark.xfail
     def test_exponentiation_array_exp_2(self):
@@ -338,12 +331,12 @@ def test_minimum(self):
 
     def test_clip_numpy_func(self):
         helpers.assert_quantity_equal(
-            pxp.clip(self.q, 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
+            pxp.clip(pxp.asarray(self.q, dtype=pxp.float32), 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
         )
 
     def test_round_numpy_func(self):
         helpers.assert_quantity_equal(
-            pxp.round(1.0275 * self.ureg.m, decimals=2), 1.03 * self.ureg.m
+            pxp.round(102.75 * self.ureg.m, ), 103 * self.ureg.m
         )
 
     def test_cumulative_sum(self):
@@ -352,19 +345,21 @@ def test_cumulative_sum(self):
         )
 
     def test_mean_numpy_func(self):
-        assert pxp.mean(self.q) == 2.5 * self.ureg.m
-        assert pxp.mean(self.q_temperature) == self.Q_(2.5, self.ureg.degC)
+        assert pxp.mean(pxp.asarray(self.q, dtype=pxp.float32)) == 2.5 * self.ureg.m
+        assert pxp.mean(pxp.asarray(self.q_temperature, dtype=pxp.float32)) == self.Q_(2.5, self.ureg.degC)
 
     def test_var_numpy_func(self):
-        assert pxp.var(self.q) == 1.25 * self.ureg.m**2
-        assert pxp.var(self.q_temperature) == 1.25 * self.ureg.delta_degC**2
+        dtype=pxp.float32
+        assert pxp.var(pxp.asarray(self.q, dtype=dtype)) == 1.25 * self.ureg.m**2
+        assert pxp.var(pxp.asarray(self.q_temperature, dtype=dtype)) == 1.25 * self.ureg.delta_degC**2
 
     def test_std_numpy_func(self):
+        dtype=pxp.float32
         helpers.assert_quantity_almost_equal(
-            pxp.std(self.q), 1.11803 * self.ureg.m, rtol=1e-5
+            pxp.std(pxp.asarray(self.q, dtype=dtype)), 1.11803 * self.ureg.m, rtol=1e-5
         )
         helpers.assert_quantity_almost_equal(
-            pxp.std(self.q_temperature), 1.11803 * self.ureg.delta_degC, rtol=1e-5
+            pxp.std(pxp.asarray(self.q_temperature, dtype=dtype)), 1.11803 * self.ureg.delta_degC, rtol=1e-5
         )
 
     def test_conj(self):
@@ -425,15 +420,15 @@ def test_reversible_op(self):
 
     def test_equal(self):
         x = self.q.magnitude
-        u = self.Q_(pxp.ones(x.shape))
+        u = pxp.ones(x.shape)
         false = pxp.zeros_like(x, dtype=pxp.bool)
 
         helpers.assert_quantity_equal(u, u)
         helpers.assert_quantity_equal(u, u.magnitude)
         helpers.assert_quantity_equal(u == 1, u.magnitude == 1)
 
-        v = self.Q_(pxp.zeros(x.shape), "m")
-        w = self.Q_(pxp.ones(x.shape), "m")
+        v = pxp.asarray((pxp.zeros(x.shape)), units = "m")
+        w = pxp.asarray((pxp.ones(x.shape)), units = "m")
         self.assertNDArrayEqual(v == 1, false)
         self.assertNDArrayEqual(
             self.Q_(pxp.zeros_like(x), "m") == self.Q_(pxp.zeros_like(x), "s"),
@@ -444,9 +439,10 @@ def test_equal(self):
         self.assertNDArrayEqual(u == v, false)
 
     def test_dtype(self):
-        u = self.Q_(pxp.arange(12, dtype="uint32"))
+        dtype=pxp.uint32
+        u = pxp.asarray([1, 2, 3], dtype=dtype)  * self.ureg.m
 
-        assert u.dtype == "uint32"
+        assert u.dtype == dtype
 
     def test_shape_numpy_func(self):
         assert pxp.asarray(self.q).shape == (2, 2)
@@ -455,8 +451,8 @@ def test_ndim_numpy_func(self):
         assert pxp.asarray(self.q).ndim == 2
 
     def test_meshgrid_numpy_func(self):
-        x = [1, 2] * self.ureg.m
-        y = [0, 50, 100] * self.ureg.mm
+        x = pxp.asarray([1, 2]) * self.ureg.m
+        y = pxp.asarray([0, 50, 100]) * self.ureg.mm
         xx, yy = pxp.meshgrid(x, y)
         helpers.assert_quantity_equal(xx, [[1, 2], [1, 2], [1, 2]] * self.ureg.m)
         helpers.assert_quantity_equal(yy, [[0, 0], [50, 50], [100, 100]] * self.ureg.mm)
@@ -478,36 +474,37 @@ def test_where(self):
             pxp.where(self.q >= 2 * self.ureg.m, self.q, 0),
             [[0, 2], [3, 4]] * self.ureg.m,
         )
+        q_float = self.q.astype(float)
         helpers.assert_quantity_equal(
-            pxp.where(self.q >= 2 * self.ureg.m, self.q, pxp.nan),
+            pxp.where(q_float >= 2 * self.ureg.m, q_float, pxp.nan),
             [[pxp.nan, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(self.q >= 3 * self.ureg.m, 0, self.q),
+            pxp.where(q_float >= 3 * self.ureg.m, 0., q_float),
             [[1, 2], [0, 0]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(self.q >= 3 * self.ureg.m, pxp.nan, self.q),
+            pxp.where(q_float >= 3 * self.ureg.m, pxp.nan, q_float),
             [[1, 2], [pxp.nan, pxp.nan]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(self.q >= 2 * self.ureg.m, self.q, pxp.asarray(pxp.nan)),
+            pxp.where(q_float >= 2 * self.ureg.m, q_float, pxp.asarray(pxp.nan)* self.ureg.m),
             [[pxp.nan, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(self.q >= 3 * self.ureg.m, pxp.asarray(pxp.nan), self.q),
+            pxp.where(q_float >= 3 * self.ureg.m, pxp.asarray(pxp.nan)* self.ureg.m, q_float),
             [[1, 2], [pxp.nan, pxp.nan]] * self.ureg.m,
         )
         with pytest.raises(DimensionalityError):
             pxp.where(
-                self.q < 2 * self.ureg.m,
-                self.q,
+                q_float < 2 * self.ureg.m,
+                q_float,
                 0 * self.ureg.J,
             )
 
         helpers.assert_quantity_equal(
-            pxp.where([-1, 0, 1] * self.ureg.m, [1, 2, 1] * self.ureg.s, pxp.nan),
-            [1, pxp.nan, 1] * self.ureg.s,
+            pxp.where(pxp.asarray([-1., 0., 1.]) * self.ureg.m, pxp.asarray([1., 2., 1.]) * self.ureg.s, pxp.nan),
+            pxp.asarray([1., pxp.nan, 1.]) * self.ureg.s,
         )
         with pytest.raises(
             ValueError,
@@ -519,5 +516,16 @@ def test_where(self):
 
     def test_tile(self):
         helpers.assert_quantity_equal(
-            pxp.tile(self.q, 2), pxp.asarray([[1, 2, 1, 2], [3, 4, 3, 4]]) * self.ureg.m
-        )
+            pxp.tile(pxp.asarray([1,2,3,4]) *self.ureg.m, (4,1)),
+            pxp.asarray([[1, 2, 3, 4],
+                         [1, 2, 3, 4],
+                         [1, 2, 3, 4],
+                         [1, 2, 3, 4]]) * self.ureg.m
+                        )
+        helpers.assert_quantity_equal(
+            pxp.tile(pxp.asarray([[1, 2], [3, 4]]) *self.ureg.m, (2,1)),
+            pxp.asarray([[1, 2],
+                        [3, 4],
+                        [1, 2],
+                        [3, 4]]) * self.ureg.m
+                        )   
\ No newline at end of file

From 4939cda650f752f1a562edd6dea139d0e68bf742 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sat, 11 Jan 2025 20:34:42 +0000
Subject: [PATCH 33/49] tests

---
 src/pint_array/__init__.py | 62 ++++++++++++++++++++++++++------------
 tests/test_array.py        | 21 +++++++------
 2 files changed, 53 insertions(+), 30 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 609891e..925f7ab 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -119,13 +119,6 @@ def __mul__(self, other):
                 return NotImplemented
             return ArrayUnitQuantity(magnitude, units)
 
-        def __gt__(self, other):
-            if hasattr(other, "units"):
-                magnitude = self._call_super_method("__gt__", other.magnitude)
-            else:
-                magnitude = self._call_super_method("__gt__", other)
-            return ArrayUnitQuantity(magnitude, None)
-
         ## Linear Algebra Methods ##
         def __matmul__(self, other):
             return mod.matmul(self, other)
@@ -197,31 +190,59 @@ def fun(self, name=name):
         "__add__",
         "__sub__",
         "__and__",
+        "__mod__",
+        # "__mul__",
+        # "__pow__",
+        "__truediv__",
+        "__divmod__",
+        "__floordiv__",
+    ]
+    # Methods that return the result of an elementwise binary operation (reflected)
+    rbinary_names = [
+        "__radd__",
+        "__rand__",
+        "__rdivmod__",
+        "__rfloordiv__",
+        "__rmod__",
+        "__rmul__",
+        "__ror__",
+        # "__rpow__",
+        "__rsub__",
+        "__rtruediv__",
+        "__rxor__",
+    ]
+    for name in binary_names + rbinary_names:
+
+        def method(self, other, name=name):
+            units = self.units
+            magnitude_other = other.m_as(units) if hasattr(other, "units") else other
+            magnitude = self._call_super_method(name, magnitude_other)
+            # FIXME: correct units for op
+            return ArrayUnitQuantity(magnitude, units)
+
+        setattr(ArrayQuantity, name, method)
+
+
+    # Methods that return the result of an elementwise binary operation
+    unitless_binary_names = [
         "__eq__",
         "__ge__",
-        # "__gt__",
+        "__gt__",
         "__le__",
-        "__lshift__",
         "__lt__",
-        "__mod__",
-        # "__mul__",
         "__ne__",
         "__or__",
-        "__pow__",
-        "__rshift__",
-        "__sub__",
         "__truediv__",
         "__xor__",
         "__divmod__",
         "__floordiv__",
     ]
     # Methods that return the result of an elementwise binary operation (reflected)
-    rbinary_names = [
+    unitless_rbinary_names = [
         "__radd__",
         "__rand__",
         "__rdivmod__",
         "__rfloordiv__",
-        "__rlshift__",
         "__rmod__",
         "__rmul__",
         "__ror__",
@@ -231,14 +252,14 @@ def fun(self, name=name):
         "__rtruediv__",
         "__rxor__",
     ]
-    for name in binary_names + rbinary_names:
+    for name in unitless_binary_names + unitless_rbinary_names:
 
         def method(self, other, name=name):
             units = self.units
             magnitude_other = other.m_as(units) if hasattr(other, "units") else other
             magnitude = self._call_super_method(name, magnitude_other)
             # FIXME: correct units for op
-            return ArrayUnitQuantity(magnitude, units)
+            return magnitude
 
         setattr(ArrayQuantity, name, method)
 
@@ -456,7 +477,8 @@ def func(x, /, *args, func_str=func_str, **kwargs):
 
         setattr(mod, func_str, func)
 
-    # Functions which ignore units on input and output
+    # Functions which ignore units on input and output, and return a bool/int
+    # as a non-Quantity array
     for func_str in (
         "argsort",
         "argmin",
@@ -468,7 +490,7 @@ def func(x, /, *args, func_str=func_str, **kwargs):
             magnitude = xp.asarray(x.magnitude, copy=True)
             xp_func = getattr(xp, func_str)
             magnitude = xp_func(magnitude, *args, **kwargs)
-            return ArrayUnitQuantity(magnitude, None)
+            return magnitude
 
         setattr(mod, func_str, func)
 
diff --git a/tests/test_array.py b/tests/test_array.py
index 3c688b9..eb0cbef 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -308,7 +308,7 @@ def test_max_with_axis_arg(self):
         helpers.assert_quantity_equal(pxp.max(self.q, axis=1), [2, 4] * self.ureg.m)
 
     def test_argmax_numpy_func(self):
-        self.assertNDArrayEqual(pxp.argmax(self.q, axis=0), pxp.asarray([1, 1]))
+        self.assertNDArrayEqual(pxp.argmax(self.q, axis=0), xp.asarray([1, 1]))
 
     def test_maximum(self):
         helpers.assert_quantity_equal(
@@ -322,7 +322,7 @@ def test_min_with_axis_arg(self):
         helpers.assert_quantity_equal(pxp.min(self.q, axis=1), [1, 3] * self.ureg.m)
 
     def test_argmin_numpy_func(self):
-        self.assertNDArrayEqual(pxp.argmin(self.q, axis=0), pxp.asarray([0, 0]))
+        self.assertNDArrayEqual(pxp.argmin(self.q, axis=0), xp.asarray([0, 0]))
 
     def test_minimum(self):
         helpers.assert_quantity_equal(
@@ -363,10 +363,11 @@ def test_std_numpy_func(self):
         )
 
     def test_conj(self):
-        helpers.assert_quantity_equal((self.q * (1 + 1j)).conj(), self.q * (1 - 1j))
-        helpers.assert_quantity_equal(
-            (self.q * (1 + 1j)).conjugate(), self.q * (1 - 1j)
-        )
+        arr = pxp.asarray(self.q, dtype = pxp.complex64)  * (1 + 1j)
+        helpers.assert_quantity_equal(pxp.conj(arr), arr * (1 - 1j))
+        # helpers.assert_quantity_equal(
+        #     (self.q * (1 + 1j)).conjugate(), self.q * (1 - 1j)
+        # )
 
     def test_getitem(self):
         with pytest.raises(IndexError):
@@ -458,11 +459,11 @@ def test_meshgrid_numpy_func(self):
         helpers.assert_quantity_equal(yy, [[0, 0], [50, 50], [100, 100]] * self.ureg.mm)
 
     def test_comparisons(self):
+        # self.assertNDArrayEqual(
+        #     pxp.asarray(self.q) > 2 * self.ureg.m, xp.asarray([[False, False], [True, True]])
+        # )
         self.assertNDArrayEqual(
-            self.q > 2 * self.ureg.m, pxp.asarray([[False, False], [True, True]])
-        )
-        self.assertNDArrayEqual(
-            self.q < 2 * self.ureg.m, pxp.asarray([[True, False], [False, False]])
+            pxp.asarray(self.q) < 2 * self.ureg.m, xp.asarray([[True, False], [False, False]])
         )
 
     def test_where(self):

From 0804790d165ea0c7f0742d0b7481cafd835145cc Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sat, 11 Jan 2025 20:39:30 +0000
Subject: [PATCH 34/49] idk

---
 tests/test_array.py | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/tests/test_array.py b/tests/test_array.py
index c9a485e..d5f8ac7 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -13,25 +13,7 @@
 
 pxp = pint_array.pint_namespace(xp)
 
-<<<<<<< HEAD
-<<<<<<< HEAD
-<<<<<<< HEAD
-=======
-
-<<<<<<< HEAD
-# @helpers.requires_numpy
->>>>>>> 1ad9ca9 (style: pre-commit fixes)
-=======
-
->>>>>>> 8498256 (style: pre-commit fixes)
-class TestNumpyMethods:
-=======
-class TestNumPyMethods:
->>>>>>> 573558d (fix xp-tests)
-=======
-
 class TestNumPyMethods:
->>>>>>> bda9eba697f92e4bfe41a3f3813e589da7048eba
     @classmethod
     def setup_class(cls):
         from pint import _DEFAULT_REGISTRY

From 1a477bb508e6fdae695b2d7a9fdb36ab15d10b4b Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sat, 11 Jan 2025 20:40:28 +0000
Subject: [PATCH 35/49] idk

---
 tests/test_array.py | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/tests/test_array.py b/tests/test_array.py
index d5f8ac7..013235d 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -295,11 +295,7 @@ def test_max_with_axis_arg(self):
         helpers.assert_quantity_equal(pxp.max(self.q, axis=1), [2, 4] * self.ureg.m)
 
     def test_argmax_numpy_func(self):
-<<<<<<< HEAD
         self.assertNDArrayEqual(pxp.argmax(self.q, axis=0), xp.asarray([1, 1]))
-=======
-        self.assertNDArrayEqual(pxp.argmax(self.q, axis=0), pxp.asarray([1, 1]))
->>>>>>> bda9eba697f92e4bfe41a3f3813e589da7048eba
 
     def test_maximum(self):
         helpers.assert_quantity_equal(
@@ -313,11 +309,7 @@ def test_min_with_axis_arg(self):
         helpers.assert_quantity_equal(pxp.min(self.q, axis=1), [1, 3] * self.ureg.m)
 
     def test_argmin_numpy_func(self):
-<<<<<<< HEAD
         self.assertNDArrayEqual(pxp.argmin(self.q, axis=0), xp.asarray([0, 0]))
-=======
-        self.assertNDArrayEqual(pxp.argmin(self.q, axis=0), pxp.asarray([0, 0]))
->>>>>>> bda9eba697f92e4bfe41a3f3813e589da7048eba
 
     def test_minimum(self):
         helpers.assert_quantity_equal(
@@ -458,14 +450,7 @@ def test_comparisons(self):
         #     pxp.asarray(self.q) > 2 * self.ureg.m, xp.asarray([[False, False], [True, True]])
         # )
         self.assertNDArrayEqual(
-<<<<<<< HEAD
             pxp.asarray(self.q) < 2 * self.ureg.m, xp.asarray([[True, False], [False, False]])
-=======
-            self.q > 2 * self.ureg.m, pxp.asarray([[False, False], [True, True]])
-        )
-        self.assertNDArrayEqual(
-            self.q < 2 * self.ureg.m, pxp.asarray([[True, False], [False, False]])
->>>>>>> bda9eba697f92e4bfe41a3f3813e589da7048eba
         )
 
     def test_where(self):

From 97ad90de2f6bdffb979d57f769892dcef212d2b6 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sat, 11 Jan 2025 21:59:52 +0000
Subject: [PATCH 36/49] tests

---
 src/pint_array/__init__.py | 26 +++++++++++++------------
 tests/test_array.py        | 40 ++++++++++++++++++--------------------
 2 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 925f7ab..4b5618c 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -119,6 +119,9 @@ def __mul__(self, other):
                 return NotImplemented
             return ArrayUnitQuantity(magnitude, units)
 
+        def __rmul__(self, other):
+            return self.__mul__(other)
+
         ## Linear Algebra Methods ##
         def __matmul__(self, other):
             return mod.matmul(self, other)
@@ -232,7 +235,6 @@ def method(self, other, name=name):
         "__lt__",
         "__ne__",
         "__or__",
-        "__truediv__",
         "__xor__",
         "__divmod__",
         "__floordiv__",
@@ -241,22 +243,21 @@ def method(self, other, name=name):
     unitless_rbinary_names = [
         "__radd__",
         "__rand__",
-        "__rdivmod__",
-        "__rfloordiv__",
-        "__rmod__",
-        "__rmul__",
         "__ror__",
         "__rpow__",
-        "__rrshift__",
-        "__rsub__",
-        "__rtruediv__",
         "__rxor__",
     ]
     for name in unitless_binary_names + unitless_rbinary_names:
 
         def method(self, other, name=name):
             units = self.units
-            magnitude_other = other.m_as(units) if hasattr(other, "units") else other
+            if name in ["__eq__", "__ne__", ]:
+                try:
+                    magnitude_other = other.m_as(units) if hasattr(other, "units") else other
+                except DimensionalityError:
+                    return xp.full_like(self.magnitude, False)
+            else:
+                magnitude_other = other.m_as(units) if hasattr(other, "units") else other
             magnitude = self._call_super_method(name, magnitude_other)
             # FIXME: correct units for op
             return magnitude
@@ -498,7 +499,7 @@ def nonzero(x, /):
         x = asarray(x)
         magnitude = xp.asarray(x.magnitude, copy=True)
         res = xp.nonzero(magnitude)
-        return tuple(ArrayUnitQuantity(magnitude_i, None) for magnitude_i in res)
+        return res
 
     mod.nonzero = nonzero
 
@@ -510,7 +511,7 @@ def searchsorted(x1, x2, /, *, side="left", sorter=None):
         magnitude_x2 = x2.m_as(x1.units)
 
         magnitude = xp.searchsorted(magnitude_x1, magnitude_x2, side=side)
-        return ArrayUnitQuantity(magnitude, None)
+        return magnitude
 
     mod.searchsorted = searchsorted
 
@@ -784,6 +785,7 @@ def pow(x1, x2, /, *args, **kwargs):
         return ArrayUnitQuantity(magnitude, units)
 
     mod.pow = pow
+    setattr(ArrayUnitQuantity, "__pow__", pow)
 
     ## Indexing Functions
     def take(x, indices, /, **kwargs):
@@ -827,7 +829,7 @@ def sort_fun(x, /, **kwargs):
 
         return sort_fun
 
-    sort_names = ["sort", "argsort"]
+    sort_names = ["sort"]
     for name in sort_names:
         setattr(mod, name, get_sort_fun(name))
 
diff --git a/tests/test_array.py b/tests/test_array.py
index 013235d..492a574 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -205,29 +205,25 @@ def test_addition_with_incompatible_scalar(self):
             op.add(b, a)
 
     def test_power(self):
-        arr = pxp.asarray(range(3), dtype=pxp.float32)
-        q = self.Q_(arr, "meter")
+        arr = xp.asarray(range(3), dtype=pxp.float32)
+        q  = pxp.asarray(range(3), dtype=pxp.float32, units="meter")
 
         for op_ in [pxp.pow]:
-            q_cp = copy.copy(q)
             with pytest.raises(DimensionalityError):
-                op_(2.0, q_cp)
-            arr_cp = copy.copy(arr)
-            q_cp = copy.copy(q)
+                op_(2.0, q)
             with pytest.raises(DimensionalityError):
-                op_(q_cp, arr_cp)
-            q_cp = copy.copy(q)
-            q2_cp = copy.copy(q)
+                op_(q, arr)
             with pytest.raises(DimensionalityError):
-                op_(q_cp, q2_cp)
+                op_(q, q)
 
+        q = pxp.asarray(self.q, dtype=pxp.float32)
         helpers.assert_quantity_equal(
-            pxp.pow(self.q, self.Q_(2)), self.Q_([[1, 4], [9, 16]], "m**2")
+            pxp.pow(q, self.Q_(2.)), pxp.asarray([[1, 4], [9, 16]], dtype=pxp.float32, units= "m**2")
         )
         helpers.assert_quantity_equal(
-            self.q ** self.Q_(2), self.Q_([[1, 4], [9, 16]], "m**2")
+            q ** self.Q_(2.), self.Q_([[1, 4], [9, 16]], "m**2")
         )
-        self.assertNDArrayEqual(arr ** self.Q_(2), pxp.asarray([0, 1, 4]))
+        self.assertNDArrayEqual(arr ** self.Q_(2.), xp.asarray([0, 1, 4]))
 
     def test_sqrt(self):
         q = self.Q_(100.0, "m**2")
@@ -264,13 +260,14 @@ def test_sort_numpy_func(self):
 
     def test_argsort_numpy_func(self):
         self.assertNDArrayEqual(
-            pxp.argsort(self.q, axis=0), pxp.asarray([[0, 0], [1, 1]])
+            pxp.argsort(pxp.asarray(self.q), axis=0), xp.asarray([[0, 0], [1, 1]])
         )
 
     def test_searchsorted_numpy_func(self):
         """Test searchsorted as numpy function."""
         q = self.q.flatten()
-        self.assertNDArrayEqual(pxp.searchsorted(q, [1.5, 2.5] * self.ureg.m), [1, 2])
+        self.assertNDArrayEqual(pxp.searchsorted(q, pxp.asarray([1.5, 2.5], units="m")), xp.asarray([1, 2])
+        )
 
     def test_nonzero_numpy_func(self):
         q = [1, 0, 5, 6, 0, 9] * self.ureg.m
@@ -399,17 +396,18 @@ def test_setitem(self):
 
     def test_reversible_op(self):
         """ """
-        x = self.q.magnitude
-        u = self.Q_(pxp.ones(x.shape))
-        helpers.assert_quantity_equal(x / self.q, u * x / self.q)
-        helpers.assert_quantity_equal(x * self.q, u * x * self.q)
+        q=pxp.asarray(self.q, dtype=pxp.float64)
+        x = xp.asarray(self.q.magnitude, dtype=xp.float64)
+        u = pxp.asarray(pxp.ones(x.shape), dtype=pxp.float64)
+        helpers.assert_quantity_equal(x / q, u * x / q)
+        helpers.assert_quantity_equal(x * q, u * x * q)
         helpers.assert_quantity_equal(x + u, u + x)
         helpers.assert_quantity_equal(x - u, -(u - x))
 
     def test_equal(self):
         x = self.q.magnitude
         u = pxp.ones(x.shape)
-        false = pxp.zeros_like(x, dtype=pxp.bool)
+        false = xp.zeros_like(x, dtype=xp.bool)
 
         helpers.assert_quantity_equal(u, u)
         helpers.assert_quantity_equal(u, u.magnitude)
@@ -419,7 +417,7 @@ def test_equal(self):
         w = pxp.asarray((pxp.ones(x.shape)), units = "m")
         self.assertNDArrayEqual(v == 1, false)
         self.assertNDArrayEqual(
-            self.Q_(pxp.zeros_like(x), "m") == self.Q_(pxp.zeros_like(x), "s"),
+            pxp.asarray(pxp.zeros_like(x), units="m") == pxp.asarray(pxp.zeros_like(x), units="s") ,
             false,
         )
         self.assertNDArrayEqual(v == w, false)

From 274dd2557e9f2c54bf369fcf0b0f1351702f1218 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 12 Jan 2025 11:00:20 +0000
Subject: [PATCH 37/49] operators

---
 src/pint_array/__init__.py |  96 ++++++++++++++++++----------
 tests/test_array.py        | 127 +++++++++++++++++++++----------------
 2 files changed, 135 insertions(+), 88 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 4b5618c..eab2e91 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -9,6 +9,7 @@
 import contextlib
 import importlib
 import inspect
+import operator
 import sys
 import textwrap
 import types
@@ -108,20 +109,6 @@ def __repr__(self):
                 f"  '{self.units}'\n)>"
             )
 
-        def __mul__(self, other):
-            if hasattr(other, "units"):
-                magnitude = self._call_super_method("__mul__", other.magnitude)
-                units = self.units * other.units
-            else:
-                magnitude = self._call_super_method("__mul__", other)
-                units = self.units
-            if magnitude is NotImplemented:
-                return NotImplemented
-            return ArrayUnitQuantity(magnitude, units)
-
-        def __rmul__(self, other):
-            return self.__mul__(other)
-
         ## Linear Algebra Methods ##
         def __matmul__(self, other):
             return mod.matmul(self, other)
@@ -193,25 +180,25 @@ def fun(self, name=name):
         "__add__",
         "__sub__",
         "__and__",
-        "__mod__",
+        # "__mod__",
         # "__mul__",
-        # "__pow__",
-        "__truediv__",
-        "__divmod__",
-        "__floordiv__",
+        # # "__pow__",
+        # "__truediv__",
+        # "__divmod__",
+        # "__floordiv__",
     ]
     # Methods that return the result of an elementwise binary operation (reflected)
     rbinary_names = [
         "__radd__",
+        "__rsub__",
         "__rand__",
         "__rdivmod__",
         "__rfloordiv__",
         "__rmod__",
-        "__rmul__",
+        # "__rmul__",
         "__ror__",
         # "__rpow__",
-        "__rsub__",
-        "__rtruediv__",
+        # "__rtruediv__",
         "__rxor__",
     ]
     for name in binary_names + rbinary_names:
@@ -225,6 +212,43 @@ def method(self, other, name=name):
 
         setattr(ArrayQuantity, name, method)
 
+    calc_unit_names = [
+        "__mul__",
+        "__rmul__",
+        "__truediv__",
+        "__rtruediv__",
+        "__floordiv__",
+        "__rfloordiv__",
+        "__mod__",
+        "__rmod__",
+    ]
+    for name in calc_unit_names:
+
+        def method(self, other, name=name):
+            other = asarray(other)
+            op = getattr(operator, name)
+            if hasattr(other, "units"):
+                magnitude = self._call_super_method(name, other.magnitude)
+                units = op(self.units, other.units)
+            else:
+                magnitude = self._call_super_method(name, other)
+                units = self.units
+            if magnitude is NotImplemented:
+                return NotImplemented
+            return ArrayUnitQuantity(magnitude, units)
+
+    def method(self, other, name=name):
+        other = asarray(other)
+        op = getattr(operator, name)
+        if hasattr(other, "units"):
+            magnitude = self._call_super_method(name, other.magnitude)
+            units = op(self.units, other.units)
+        else:
+            magnitude = self._call_super_method(name, other)
+            units = self.units
+        if magnitude is NotImplemented:
+            return NotImplemented
+        return ArrayUnitQuantity(magnitude, units)
 
     # Methods that return the result of an elementwise binary operation
     unitless_binary_names = [
@@ -251,16 +275,21 @@ def method(self, other, name=name):
 
         def method(self, other, name=name):
             units = self.units
-            if name in ["__eq__", "__ne__", ]:
+            if name in [
+                "__eq__",
+                "__ne__",
+            ]:
                 try:
-                    magnitude_other = other.m_as(units) if hasattr(other, "units") else other
+                    magnitude_other = (
+                        other.m_as(units) if hasattr(other, "units") else other
+                    )
                 except DimensionalityError:
                     return xp.full_like(self.magnitude, False)
             else:
-                magnitude_other = other.m_as(units) if hasattr(other, "units") else other
-            magnitude = self._call_super_method(name, magnitude_other)
-            # FIXME: correct units for op
-            return magnitude
+                magnitude_other = (
+                    other.m_as(units) if hasattr(other, "units") else other
+                )
+            return self._call_super_method(name, magnitude_other)
 
         setattr(ArrayQuantity, name, method)
 
@@ -490,16 +519,14 @@ def func(x, /, *args, func_str=func_str, **kwargs):
             x = asarray(x)
             magnitude = xp.asarray(x.magnitude, copy=True)
             xp_func = getattr(xp, func_str)
-            magnitude = xp_func(magnitude, *args, **kwargs)
-            return magnitude
+            return xp_func(magnitude, *args, **kwargs)
 
         setattr(mod, func_str, func)
 
     def nonzero(x, /):
         x = asarray(x)
         magnitude = xp.asarray(x.magnitude, copy=True)
-        res = xp.nonzero(magnitude)
-        return res
+        return xp.nonzero(magnitude)
 
     mod.nonzero = nonzero
 
@@ -510,8 +537,7 @@ def searchsorted(x1, x2, /, *, side="left", sorter=None):
         magnitude_x1 = xp.asarray(x1.magnitude, copy=True)
         magnitude_x2 = x2.m_as(x1.units)
 
-        magnitude = xp.searchsorted(magnitude_x1, magnitude_x2, side=side)
-        return magnitude
+        return xp.searchsorted(magnitude_x1, magnitude_x2, side=side)
 
     mod.searchsorted = searchsorted
 
@@ -785,7 +811,7 @@ def pow(x1, x2, /, *args, **kwargs):
         return ArrayUnitQuantity(magnitude, units)
 
     mod.pow = pow
-    setattr(ArrayUnitQuantity, "__pow__", pow)
+    ArrayUnitQuantity.__pow__ = pow
 
     ## Indexing Functions
     def take(x, indices, /, **kwargs):
diff --git a/tests/test_array.py b/tests/test_array.py
index 492a574..31d7aea 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -13,6 +13,7 @@
 
 pxp = pint_array.pint_namespace(xp)
 
+
 class TestNumPyMethods:
     @classmethod
     def setup_class(cls):
@@ -44,7 +45,7 @@ def q_zero_or_nan(self):
 
     @property
     def q_temperature(self):
-        return pxp.asarray([[1, 2], [3, 4]], units = self.ureg.degC)
+        return pxp.asarray([[1, 2], [3, 4]], units=self.ureg.degC)
 
     def assertNDArrayEqual(self, actual, desired):
         # Assert that the given arrays are equal, and are not Quantities
@@ -83,7 +84,7 @@ class TestNumPyArrayManipulation(TestNumPyMethods):
 
     def test_reshape(self):
         helpers.assert_quantity_equal(
-            pxp.reshape(self.q, [1, 4]), pxp.asarray([[1, 2, 3, 4]] ) * self.ureg.m
+            pxp.reshape(self.q, [1, 4]), pxp.asarray([[1, 2, 3, 4]]) * self.ureg.m
         )
 
     # Transpose-like operations
@@ -113,13 +114,14 @@ def test_broadcast_to(self):
 
     def test_expand_dims(self):
         helpers.assert_quantity_equal(
-            pxp.expand_dims(self.q, axis=0), pxp.asarray([[[1, 2], [3, 4]]]) * self.ureg.m
+            pxp.expand_dims(self.q, axis=0),
+            pxp.asarray([[[1, 2], [3, 4]]]) * self.ureg.m,
         )
 
     def test_squeeze(self):
         helpers.assert_quantity_equal(
-            pxp.squeeze(pxp.asarray([[[0], [1], [2]]]) *self.ureg.m, axis=0),
-            pxp.asarray([0,1,2]) * self.ureg.m
+            pxp.squeeze(pxp.asarray([[[0], [1], [2]]]) * self.ureg.m, axis=0),
+            pxp.asarray([0, 1, 2]) * self.ureg.m,
         )
 
     # Changing number of dimensions
@@ -129,7 +131,7 @@ def test_concat_stack(self, subtests):
         for func in (pxp.concat, pxp.stack):
             with subtests.test(func=func):
                 helpers.assert_quantity_equal(
-                    func([self.q] * 2), pxp.asarray(func([self.q.m] * 2), units = "m")
+                    func([self.q] * 2), pxp.asarray(func([self.q.m] * 2), units="m")
                 )
                 # One or more of the args is a bare array full of zeros or NaNs
                 # helpers.assert_quantity_equal(
@@ -144,9 +146,9 @@ def test_concat_stack(self, subtests):
                     func([nz.m, self.q])
 
     def test_astype(self):
-        dtype=pxp.float32
+        dtype = pxp.float32
         actual = pxp.astype(self.q, dtype)
-        expected = pxp.asarray([[1.0, 2.0], [3.0, 4.0]], dtype=dtype, units = "m")
+        expected = pxp.asarray([[1.0, 2.0], [3.0, 4.0]], dtype=dtype, units="m")
         helpers.assert_quantity_equal(actual, expected)
         assert actual.m.dtype == expected.m.dtype
 
@@ -154,12 +156,12 @@ def test_item(self):
         helpers.assert_quantity_equal(self.Q_([[0]], "m").item(), 0 * self.ureg.m)
 
     def test_broadcast_arrays(self):
-        x = pxp.asarray([[1, 2, 3]], units= "m")
-        y = pxp.asarray([[4], [5]], units= "nm")
+        x = pxp.asarray([[1, 2, 3]], units="m")
+        y = pxp.asarray([[4], [5]], units="nm")
         result = pxp.broadcast_arrays(x, y)
         expected = (
-            pxp.asarray([[1, 2, 3], [1, 2, 3]], units= "m"),
-            pxp.asarray([[4, 4, 4], [5, 5, 5]], units= "nm")
+            pxp.asarray([[1, 2, 3], [1, 2, 3]], units="m"),
+            pxp.asarray([[4, 4, 4], [5, 5, 5]], units="nm"),
         )
         helpers.assert_quantity_equal(result, expected)
 
@@ -187,13 +189,13 @@ def test_sum_numpy_func(self):
 
     # Arithmetic operations
     def test_addition_with_scalar(self):
-        a = pxp.asarray([0, 1, 2], dtype = pxp.float32)
+        a = pxp.asarray([0, 1, 2], dtype=pxp.float32)
         b = 10.0 * self.ureg("gram/kilogram")
         helpers.assert_quantity_almost_equal(
-            a + b, pxp.asarray([0.01, 1.01, 2.01], units = "")
+            a + b, pxp.asarray([0.01, 1.01, 2.01], units="")
         )
         helpers.assert_quantity_almost_equal(
-            b + a, pxp.asarray([0.01, 1.01, 2.01], units = "")
+            b + a, pxp.asarray([0.01, 1.01, 2.01], units="")
         )
 
     def test_addition_with_incompatible_scalar(self):
@@ -206,7 +208,7 @@ def test_addition_with_incompatible_scalar(self):
 
     def test_power(self):
         arr = xp.asarray(range(3), dtype=pxp.float32)
-        q  = pxp.asarray(range(3), dtype=pxp.float32, units="meter")
+        q = pxp.asarray(range(3), dtype=pxp.float32, units="meter")
 
         for op_ in [pxp.pow]:
             with pytest.raises(DimensionalityError):
@@ -218,12 +220,13 @@ def test_power(self):
 
         q = pxp.asarray(self.q, dtype=pxp.float32)
         helpers.assert_quantity_equal(
-            pxp.pow(q, self.Q_(2.)), pxp.asarray([[1, 4], [9, 16]], dtype=pxp.float32, units= "m**2")
+            pxp.pow(q, self.Q_(2.0)),
+            pxp.asarray([[1, 4], [9, 16]], dtype=pxp.float32, units="m**2"),
         )
         helpers.assert_quantity_equal(
-            q ** self.Q_(2.), self.Q_([[1, 4], [9, 16]], "m**2")
+            q ** self.Q_(2.0), self.Q_([[1, 4], [9, 16]], "m**2")
         )
-        self.assertNDArrayEqual(arr ** self.Q_(2.), xp.asarray([0, 1, 4]))
+        self.assertNDArrayEqual(arr ** self.Q_(2.0), xp.asarray([0, 1, 4]))
 
     def test_sqrt(self):
         q = self.Q_(100.0, "m**2")
@@ -266,7 +269,8 @@ def test_argsort_numpy_func(self):
     def test_searchsorted_numpy_func(self):
         """Test searchsorted as numpy function."""
         q = self.q.flatten()
-        self.assertNDArrayEqual(pxp.searchsorted(q, pxp.asarray([1.5, 2.5], units="m")), xp.asarray([1, 2])
+        self.assertNDArrayEqual(
+            pxp.searchsorted(q, pxp.asarray([1.5, 2.5], units="m")), xp.asarray([1, 2])
         )
 
     def test_nonzero_numpy_func(self):
@@ -315,12 +319,16 @@ def test_minimum(self):
 
     def test_clip_numpy_func(self):
         helpers.assert_quantity_equal(
-            pxp.clip(pxp.asarray(self.q, dtype=pxp.float32), 150 * self.ureg.cm, None), [[1.5, 2], [3, 4]] * self.ureg.m
+            pxp.clip(pxp.asarray(self.q, dtype=pxp.float32), 150 * self.ureg.cm, None),
+            [[1.5, 2], [3, 4]] * self.ureg.m,
         )
 
     def test_round_numpy_func(self):
         helpers.assert_quantity_equal(
-            pxp.round(102.75 * self.ureg.m, ), 103 * self.ureg.m
+            pxp.round(
+                102.75 * self.ureg.m,
+            ),
+            103 * self.ureg.m,
         )
 
     def test_cumulative_sum(self):
@@ -330,24 +338,31 @@ def test_cumulative_sum(self):
 
     def test_mean_numpy_func(self):
         assert pxp.mean(pxp.asarray(self.q, dtype=pxp.float32)) == 2.5 * self.ureg.m
-        assert pxp.mean(pxp.asarray(self.q_temperature, dtype=pxp.float32)) == self.Q_(2.5, self.ureg.degC)
+        assert pxp.mean(pxp.asarray(self.q_temperature, dtype=pxp.float32)) == self.Q_(
+            2.5, self.ureg.degC
+        )
 
     def test_var_numpy_func(self):
-        dtype=pxp.float32
+        dtype = pxp.float32
         assert pxp.var(pxp.asarray(self.q, dtype=dtype)) == 1.25 * self.ureg.m**2
-        assert pxp.var(pxp.asarray(self.q_temperature, dtype=dtype)) == 1.25 * self.ureg.delta_degC**2
+        assert (
+            pxp.var(pxp.asarray(self.q_temperature, dtype=dtype))
+            == 1.25 * self.ureg.delta_degC**2
+        )
 
     def test_std_numpy_func(self):
-        dtype=pxp.float32
+        dtype = pxp.float32
         helpers.assert_quantity_almost_equal(
             pxp.std(pxp.asarray(self.q, dtype=dtype)), 1.11803 * self.ureg.m, rtol=1e-5
         )
         helpers.assert_quantity_almost_equal(
-            pxp.std(pxp.asarray(self.q_temperature, dtype=dtype)), 1.11803 * self.ureg.delta_degC, rtol=1e-5
+            pxp.std(pxp.asarray(self.q_temperature, dtype=dtype)),
+            1.11803 * self.ureg.delta_degC,
+            rtol=1e-5,
         )
 
     def test_conj(self):
-        arr = pxp.asarray(self.q, dtype = pxp.complex64)  * (1 + 1j)
+        arr = pxp.asarray(self.q, dtype=pxp.complex64) * (1 + 1j)
         helpers.assert_quantity_equal(pxp.conj(arr), arr * (1 - 1j))
         # helpers.assert_quantity_equal(
         #     (self.q * (1 + 1j)).conjugate(), self.q * (1 - 1j)
@@ -396,7 +411,7 @@ def test_setitem(self):
 
     def test_reversible_op(self):
         """ """
-        q=pxp.asarray(self.q, dtype=pxp.float64)
+        q = pxp.asarray(self.q, dtype=pxp.float64)
         x = xp.asarray(self.q.magnitude, dtype=xp.float64)
         u = pxp.asarray(pxp.ones(x.shape), dtype=pxp.float64)
         helpers.assert_quantity_equal(x / q, u * x / q)
@@ -413,11 +428,12 @@ def test_equal(self):
         helpers.assert_quantity_equal(u, u.magnitude)
         helpers.assert_quantity_equal(u == 1, u.magnitude == 1)
 
-        v = pxp.asarray((pxp.zeros(x.shape)), units = "m")
-        w = pxp.asarray((pxp.ones(x.shape)), units = "m")
+        v = pxp.asarray((pxp.zeros(x.shape)), units="m")
+        w = pxp.asarray((pxp.ones(x.shape)), units="m")
         self.assertNDArrayEqual(v == 1, false)
         self.assertNDArrayEqual(
-            pxp.asarray(pxp.zeros_like(x), units="m") == pxp.asarray(pxp.zeros_like(x), units="s") ,
+            pxp.asarray(pxp.zeros_like(x), units="m")
+            == pxp.asarray(pxp.zeros_like(x), units="s"),
             false,
         )
         self.assertNDArrayEqual(v == w, false)
@@ -425,8 +441,8 @@ def test_equal(self):
         self.assertNDArrayEqual(u == v, false)
 
     def test_dtype(self):
-        dtype=pxp.uint32
-        u = pxp.asarray([1, 2, 3], dtype=dtype)  * self.ureg.m
+        dtype = pxp.uint32
+        u = pxp.asarray([1, 2, 3], dtype=dtype) * self.ureg.m
 
         assert u.dtype == dtype
 
@@ -445,10 +461,12 @@ def test_meshgrid_numpy_func(self):
 
     def test_comparisons(self):
         # self.assertNDArrayEqual(
-        #     pxp.asarray(self.q) > 2 * self.ureg.m, xp.asarray([[False, False], [True, True]])
+        #     pxp.asarray(self.q) > 2 * self.ureg.m,
+        #     xp.asarray([[False, False], [True, True]])
         # )
         self.assertNDArrayEqual(
-            pxp.asarray(self.q) < 2 * self.ureg.m, xp.asarray([[True, False], [False, False]])
+            pxp.asarray(self.q) < 2 * self.ureg.m,
+            xp.asarray([[True, False], [False, False]]),
         )
 
     def test_where(self):
@@ -466,7 +484,7 @@ def test_where(self):
             [[pxp.nan, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(q_float >= 3 * self.ureg.m, 0., q_float),
+            pxp.where(q_float >= 3 * self.ureg.m, 0.0, q_float),
             [[1, 2], [0, 0]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
@@ -474,11 +492,15 @@ def test_where(self):
             [[1, 2], [pxp.nan, pxp.nan]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(q_float >= 2 * self.ureg.m, q_float, pxp.asarray(pxp.nan)* self.ureg.m),
+            pxp.where(
+                q_float >= 2 * self.ureg.m, q_float, pxp.asarray(pxp.nan) * self.ureg.m
+            ),
             [[pxp.nan, 2], [3, 4]] * self.ureg.m,
         )
         helpers.assert_quantity_equal(
-            pxp.where(q_float >= 3 * self.ureg.m, pxp.asarray(pxp.nan)* self.ureg.m, q_float),
+            pxp.where(
+                q_float >= 3 * self.ureg.m, pxp.asarray(pxp.nan) * self.ureg.m, q_float
+            ),
             [[1, 2], [pxp.nan, pxp.nan]] * self.ureg.m,
         )
         with pytest.raises(DimensionalityError):
@@ -489,8 +511,12 @@ def test_where(self):
             )
 
         helpers.assert_quantity_equal(
-            pxp.where(pxp.asarray([-1., 0., 1.]) * self.ureg.m, pxp.asarray([1., 2., 1.]) * self.ureg.s, pxp.nan),
-            pxp.asarray([1., pxp.nan, 1.]) * self.ureg.s,
+            pxp.where(
+                pxp.asarray([-1.0, 0.0, 1.0]) * self.ureg.m,
+                pxp.asarray([1.0, 2.0, 1.0]) * self.ureg.s,
+                pxp.nan,
+            ),
+            pxp.asarray([1.0, pxp.nan, 1.0]) * self.ureg.s,
         )
         with pytest.raises(
             ValueError,
@@ -502,16 +528,11 @@ def test_where(self):
 
     def test_tile(self):
         helpers.assert_quantity_equal(
-            pxp.tile(pxp.asarray([1,2,3,4]) *self.ureg.m, (4,1)),
-            pxp.asarray([[1, 2, 3, 4],
-                         [1, 2, 3, 4],
-                         [1, 2, 3, 4],
-                         [1, 2, 3, 4]]) * self.ureg.m
-                        )
+            pxp.tile(pxp.asarray([1, 2, 3, 4]) * self.ureg.m, (4, 1)),
+            pxp.asarray([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])
+            * self.ureg.m,
+        )
         helpers.assert_quantity_equal(
-            pxp.tile(pxp.asarray([[1, 2], [3, 4]]) *self.ureg.m, (2,1)),
-            pxp.asarray([[1, 2],
-                        [3, 4],
-                        [1, 2],
-                        [3, 4]]) * self.ureg.m
-                        )   
\ No newline at end of file
+            pxp.tile(pxp.asarray([[1, 2], [3, 4]]) * self.ureg.m, (2, 1)),
+            pxp.asarray([[1, 2], [3, 4], [1, 2], [3, 4]]) * self.ureg.m,
+        )

From 10c204248b98aba641366b998c7394e32c734b85 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 12 Jan 2025 11:36:58 +0000
Subject: [PATCH 38/49] set/get item

---
 src/pint_array/__init__.py | 10 +++++++---
 tests/test_array.py        | 10 +++++-----
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index eab2e91..e4f7374 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -93,9 +93,13 @@ def __getitem__(self, key):
 
         def __setitem__(self, key, other):
             key = self._validate_key(key)
-            magnitude_other = (
-                other.m_as(self.units) if hasattr(other, "units") else other
-            )
+            if hasattr(other, "units"):
+                magnitude_other = other.m_as(self.units)
+            elif self.units.dimensionless:
+                magnitude_other = other
+            else:
+                other_units = "dimensionless"
+                raise DimensionalityError(other_units, self.units)
             return self.magnitude.__setitem__(key, magnitude_other)
 
         def __iter__(self):
diff --git a/tests/test_array.py b/tests/test_array.py
index 31d7aea..5ae1308 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -371,7 +371,7 @@ def test_conj(self):
     def test_getitem(self):
         with pytest.raises(IndexError):
             self.q.__getitem__((0, 10))
-        helpers.assert_quantity_equal(self.q[0], [1, 2] * self.ureg.m)
+        helpers.assert_quantity_equal(self.q[0, :], [1, 2] * self.ureg.m)
         assert self.q[1, 1] == 4 * self.ureg.m
 
     def test_setitem(self):
@@ -387,7 +387,7 @@ def test_setitem(self):
             self.q[0] = 1 * self.ureg.J
 
         q = self.q.copy()
-        q[0] = 1 * self.ureg.m
+        q[0, :] = 1 * self.ureg.m
         helpers.assert_quantity_equal(q, [[1, 1], [3, 4]] * self.ureg.m)
 
         q = self.q.copy()
@@ -395,14 +395,14 @@ def test_setitem(self):
         helpers.assert_quantity_equal(q, [[1, 1], [1, 1]] * self.ureg.m)
 
         q = self.q.copy()
-        q[:] = 1 * self.ureg.m
+        q[:, :] = 1 * self.ureg.m
         helpers.assert_quantity_equal(q, [[1, 1], [1, 1]] * self.ureg.m)
 
         # check and see that dimensionless numbers work correctly
-        q = [0, 1, 2, 3] * self.ureg.dimensionless
+        q = pxp.asarray([0, 1, 2, 3], units=self.ureg.dimensionless)
         q[0] = 1
         helpers.assert_quantity_equal(q, pxp.asarray([1, 1, 2, 3]))
-        q[0] = self.ureg.m / self.ureg.mm
+        q[0] = 1 * self.ureg.m / self.ureg.mm
         helpers.assert_quantity_equal(q, pxp.asarray([1000, 1, 2, 3]))
 
         q = [0.0, 1.0, 2.0, 3.0] * self.ureg.m / self.ureg.mm

From 5431cc9358b15f6abd30fe2ddd43049289ab6f6f Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 12 Jan 2025 13:01:22 +0000
Subject: [PATCH 39/49] xfails

---
 src/pint_array/__init__.py | 1 +
 xp-tests-xfails.txt        | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index e4f7374..e99fdd5 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -536,6 +536,7 @@ def nonzero(x, /):
 
     def searchsorted(x1, x2, /, *, side="left", sorter=None):
         if sorter is not None:
+            x1 = asarray(x1)
             x1 = take(x1, sorter)
 
         magnitude_x1 = xp.asarray(x1.magnitude, copy=True)
diff --git a/xp-tests-xfails.txt b/xp-tests-xfails.txt
index 6369ae4..22e7bc1 100644
--- a/xp-tests-xfails.txt
+++ b/xp-tests-xfails.txt
@@ -36,7 +36,13 @@ array_api_tests/test_has_names.py::test_has_names[linalg-tensordot]
 array_api_tests/test_has_names.py::test_has_names[linalg-trace]
 array_api_tests/test_has_names.py::test_has_names[linalg-vecdot]
 array_api_tests/test_has_names.py::test_has_names[linalg-vector_norm]
+array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__lshift__(x1, x2)]
+array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__lshift__(x, s)]
+array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x1, x2)]
+array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x, s)]
 # flaky on macos
 array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt
 # `pow` with array x2 is only defined when all elements of x2 are equal
 array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)]
+array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x1, x2)]
+array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)]

From 83997b70ceb07ab881892162f7d7dccd6897e3fd Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 12 Jan 2025 13:06:29 +0000
Subject: [PATCH 40/49] take

---
 src/pint_array/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index e99fdd5..43ca353 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -536,7 +536,6 @@ def nonzero(x, /):
 
     def searchsorted(x1, x2, /, *, side="left", sorter=None):
         if sorter is not None:
-            x1 = asarray(x1)
             x1 = take(x1, sorter)
 
         magnitude_x1 = xp.asarray(x1.magnitude, copy=True)
@@ -820,6 +819,7 @@ def pow(x1, x2, /, *args, **kwargs):
 
     ## Indexing Functions
     def take(x, indices, /, **kwargs):
+        x = asarray(x)
         magnitude = xp.take(x.magnitude, indices.magnitude, **kwargs)
         return ArrayUnitQuantity(magnitude, x.units)
 

From 74f7b6bde6427d45f7272965abc22c24280fe05c Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 12 Jan 2025 13:30:39 +0000
Subject: [PATCH 41/49] take

---
 src/pint_array/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 43ca353..6745146 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -820,7 +820,7 @@ def pow(x1, x2, /, *args, **kwargs):
     ## Indexing Functions
     def take(x, indices, /, **kwargs):
         x = asarray(x)
-        magnitude = xp.take(x.magnitude, indices.magnitude, **kwargs)
+        magnitude = xp.take(x.magnitude, indices, **kwargs)
         return ArrayUnitQuantity(magnitude, x.units)
 
     mod.take = take

From 1a3bddbf25d288c930e047b66f51ad38b520a5d7 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 12 Jan 2025 19:44:43 +0000
Subject: [PATCH 42/49] review fixes

---
 src/pint_array/__init__.py | 27 ++++-----------------------
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 6745146..c1e0da3 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -241,19 +241,6 @@ def method(self, other, name=name):
                 return NotImplemented
             return ArrayUnitQuantity(magnitude, units)
 
-    def method(self, other, name=name):
-        other = asarray(other)
-        op = getattr(operator, name)
-        if hasattr(other, "units"):
-            magnitude = self._call_super_method(name, other.magnitude)
-            units = op(self.units, other.units)
-        else:
-            magnitude = self._call_super_method(name, other)
-            units = self.units
-        if magnitude is NotImplemented:
-            return NotImplemented
-        return ArrayUnitQuantity(magnitude, units)
-
     # Methods that return the result of an elementwise binary operation
     unitless_binary_names = [
         "__eq__",
@@ -361,9 +348,8 @@ def fun(*args, func_str=func_str, units=None, **kwargs):
         setattr(mod, func_str, fun)
 
     ## Manipulation Functions ##
-    first_arg_arrays = {"broadcast_arrays", "concat", "stack", "meshgrid"}
-    output_arrays = {"broadcast_arrays", "unstack", "meshgrid"}
-    arbitrary_num_arrays = {"broadcast_arrays", "meshgrid"}
+    first_arg_arrays = {"concat", "stack"}
+    output_arrays = {"unstack"}
 
     def get_manip_fun(func_str):
         def manip_fun(x, *args, **kwargs):
@@ -395,11 +381,7 @@ def manip_fun(x, *args, **kwargs):
             ):
                 args[0] = repeats.magnitude
 
-            if func_str in arbitrary_num_arrays and not one_array:
-                args = [asarray(arg, units=x[0].units).magnitude for arg in args]
-                magnitude = xp_func(*magnitude, *args, **kwargs)
-            else:
-                magnitude = xp_func(magnitude, *args, **kwargs)
+            magnitude = xp_func(magnitude, *args, **kwargs)
 
             if func_str in output_arrays:
                 return tuple(
@@ -411,7 +393,6 @@ def manip_fun(x, *args, **kwargs):
 
     creation_manip_functions = ["tril", "triu"]
     manip_names = [
-        "broadcast_arrays",
         "broadcast_to",
         "concat",
         "expand_dims",
@@ -430,7 +411,7 @@ def manip_fun(x, *args, **kwargs):
         setattr(mod, name, get_manip_fun(name))
 
     def _meshgrid(*xi, **kwargs):
-        # Simply need to map input units to onto list of outputs
+        # Simply need to map input units onto list of outputs
         input_units = (x.units for x in xi)
         res = xp.meshgrid(*(x.magnitude for x in xi), **kwargs)
         return [out * unit for out, unit in zip(res, input_units, strict=False)]

From a7ff500eabd97221316958c261a94c310dbececf Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 12 Jan 2025 19:45:58 +0000
Subject: [PATCH 43/49] take

---
 src/pint_array/__init__.py | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index c1e0da3..d81f3ec 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -693,16 +693,15 @@ def fun(x, /, *args, func_str=func_str, **kwargs):
 
         setattr(mod, func_str, fun)
 
-    for func_str in ["sqrt"]:
 
-        def fun(x, /, *args, func_str=func_str, **kwargs):
-            x = asarray(x)
-            magnitude = xp.asarray(x.magnitude, copy=True)
-            magnitude = getattr(xp, func_str)(magnitude, *args, **kwargs)
-            return ArrayUnitQuantity(magnitude, x.units**0.5)
-
-        setattr(mod, func_str, fun)
+    def _sqrt(x, /, *args, **kwargs):
+        x = asarray(x)
+        magnitude = xp.asarray(x.magnitude, copy=True)
+        magnitude = getattr(xp, "sqrt")(magnitude, *args, **kwargs)
+        return ArrayUnitQuantity(magnitude, x.units**0.5)
 
+    mod.sqrt = _sqrt
+    
     elementwise_two_arrays = [
         "add",
         "atan2",

From 314e2c600007e2049e6412a231ed4d0e5f082238 Mon Sep 17 00:00:00 2001
From: Andrew <andrewgsavage@gmail.com>
Date: Sun, 12 Jan 2025 19:48:05 +0000
Subject: [PATCH 44/49] sort

---
 src/pint_array/__init__.py | 23 +++++++++--------------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index d81f3ec..fc3a14f 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -701,7 +701,7 @@ def _sqrt(x, /, *args, **kwargs):
         return ArrayUnitQuantity(magnitude, x.units**0.5)
 
     mod.sqrt = _sqrt
-    
+
     elementwise_two_arrays = [
         "add",
         "atan2",
@@ -829,20 +829,15 @@ def matrix_transpose(x):
     mod.matrix_transpose = matrix_transpose
 
     ## Sorting Functions ##
-    def get_sort_fun(func_str):
-        def sort_fun(x, /, **kwargs):
-            x = asarray(x)
-            magnitude = xp.asarray(x.magnitude, copy=True)
-            xp_func = getattr(xp, func_str)
-            magnitude = xp_func(magnitude, **kwargs)
-            units = x.units if func_str == "sort" else None
-            return ArrayUnitQuantity(magnitude, units)
-
-        return sort_fun
+    def _sort(x, /, **kwargs):
+        x = asarray(x)
+        magnitude = xp.asarray(x.magnitude, copy=True)
+        xp_func = getattr(xp, "sort")
+        magnitude = xp_func(magnitude, **kwargs)
+        units = x.units 
+        return ArrayUnitQuantity(magnitude, units)
 
-    sort_names = ["sort"]
-    for name in sort_names:
-        setattr(mod, name, get_sort_fun(name))
+    mod.sort = _sort
 
     ## Set Functions ##
     def get_set_fun(func_str):

From 18638d60045ce02341f545f0bbd205fd7f98ba2a Mon Sep 17 00:00:00 2001
From: Andrew Savage <andrewgsavage@gmail.com>
Date: Mon, 13 Jan 2025 20:51:03 +0000
Subject: [PATCH 45/49] power

---
 src/pint_array/__init__.py | 9 ++++++---
 xp-tests-xfails.txt        | 6 +-----
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index fc3a14f..8a864be 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -780,16 +780,19 @@ def pow(x1, x2, /, *args, **kwargs):
             units = x1.units ** as_scalar(x2_magnitude)
         else:
             x2_first_elem_magnitude = x2[(0,) * x2.ndim]
-            if not xp.all(x2_magnitude == x2_first_elem_magnitude):
+            if x1.unitless:
+                units = "dimensionless"
+            elif not xp.all(x2_magnitude == x2_first_elem_magnitude):
                 extra_msg = (
-                    "The exponent must be a scalar or an array of all the same value."
+                    "The first array must be unitless, or the exponent must be a scalar or an array of all the same value."
                 )
                 raise DimensionalityError(
                     x2.units,
                     "dimensionless",
                     extra_msg=extra_msg,
                 )
-            units = x1.units ** as_scalar(x2_first_elem_magnitude)
+            else:
+                units = x1.units ** as_scalar(x2_first_elem_magnitude)
 
         magnitude = xp.pow(x1.magnitude, x2_magnitude, *args, **kwargs)
         return ArrayUnitQuantity(magnitude, units)
diff --git a/xp-tests-xfails.txt b/xp-tests-xfails.txt
index 22e7bc1..abe3124 100644
--- a/xp-tests-xfails.txt
+++ b/xp-tests-xfails.txt
@@ -41,8 +41,4 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_s
 array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x1, x2)]
 array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x, s)]
 # flaky on macos
-array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt
-# `pow` with array x2 is only defined when all elements of x2 are equal
-array_api_tests/test_operators_and_elementwise_functions.py::test_pow[pow(x1, x2)]
-array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x1, x2)]
-array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)]
+array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt
\ No newline at end of file

From bcc5b69ababf78273468447a0527580cadc0b821 Mon Sep 17 00:00:00 2001
From: Andrew Savage <andrewgsavage@gmail.com>
Date: Mon, 13 Jan 2025 20:53:25 +0000
Subject: [PATCH 46/49] power

---
 xp-tests-xfails.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/xp-tests-xfails.txt b/xp-tests-xfails.txt
index abe3124..1dccbbf 100644
--- a/xp-tests-xfails.txt
+++ b/xp-tests-xfails.txt
@@ -41,4 +41,6 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_s
 array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x1, x2)]
 array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x, s)]
 # flaky on macos
-array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt
\ No newline at end of file
+array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt
+# `pow` with array x2 is only defined when all elements of x2 are equal
+#array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)]

From 898ce8474aa447d5f897a047e2360542a8d66e49 Mon Sep 17 00:00:00 2001
From: Andrew Savage <andrewgsavage@gmail.com>
Date: Mon, 13 Jan 2025 20:58:47 +0000
Subject: [PATCH 47/49] power

---
 xp-tests-xfails.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xp-tests-xfails.txt b/xp-tests-xfails.txt
index 1dccbbf..95d6393 100644
--- a/xp-tests-xfails.txt
+++ b/xp-tests-xfails.txt
@@ -43,4 +43,4 @@ array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_
 # flaky on macos
 array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt
 # `pow` with array x2 is only defined when all elements of x2 are equal
-#array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)]
+array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)]

From 072e40d3ccbdc6807aa3d2d7a7fb11b049dccdd9 Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Sun, 19 Jan 2025 12:52:38 +0000
Subject: [PATCH 48/49] bring back lshift, rshift

---
 src/pint_array/__init__.py | 2 ++
 xp-tests-xfails.txt        | 6 +-----
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/pint_array/__init__.py b/src/pint_array/__init__.py
index 8a864be..31cf912 100644
--- a/src/pint_array/__init__.py
+++ b/src/pint_array/__init__.py
@@ -184,6 +184,8 @@ def fun(self, name=name):
         "__add__",
         "__sub__",
         "__and__",
+        "__lshift__",
+        "__rshift__",
         # "__mod__",
         # "__mul__",
         # # "__pow__",
diff --git a/xp-tests-xfails.txt b/xp-tests-xfails.txt
index 95d6393..31d1632 100644
--- a/xp-tests-xfails.txt
+++ b/xp-tests-xfails.txt
@@ -36,11 +36,7 @@ array_api_tests/test_has_names.py::test_has_names[linalg-tensordot]
 array_api_tests/test_has_names.py::test_has_names[linalg-trace]
 array_api_tests/test_has_names.py::test_has_names[linalg-vecdot]
 array_api_tests/test_has_names.py::test_has_names[linalg-vector_norm]
-array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__lshift__(x1, x2)]
-array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_left_shift[__lshift__(x, s)]
-array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x1, x2)]
-array_api_tests/test_operators_and_elementwise_functions.py::test_bitwise_right_shift[__rshift__(x, s)]
 # flaky on macos
 array_api_tests/test_operators_and_elementwise_functions.py::test_sqrt
-# `pow` with array x2 is only defined when all elements of x2 are equal
+# dtype behaviour is not robust
 array_api_tests/test_operators_and_elementwise_functions.py::test_pow[__pow__(x, s)]

From 4714160c5c7fc0741a320253c9023afe0ee1be81 Mon Sep 17 00:00:00 2001
From: Lucas Colley <lucas.colley8@gmail.com>
Date: Sun, 19 Jan 2025 13:09:00 +0000
Subject: [PATCH 49/49] clean up tests

---
 pixi.lock           | 332 ++++++++++++++++++++++----------------------
 tests/test_array.py |  33 ++---
 2 files changed, 177 insertions(+), 188 deletions(-)

diff --git a/pixi.lock b/pixi.lock
index 523ac68..1e065e6 100644
--- a/pixi.lock
+++ b/pixi.lock
@@ -19,7 +19,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.124.1-pyha770c72_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_2.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libblas-3.9.0-26_linux64_openblas.conda
@@ -34,12 +34,12 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.6.3-hb9d3cd8_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libopenblas-0.3.28-pthreads_h94d23a6_1.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.47.2-hee588c1_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.48.0-hee588c1_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-14.2.0-hc0a3c3a_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_2.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ndindex-1.9.2-py310ha75aee5_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py310h5851e9f_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
@@ -54,13 +54,13 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/python-3.10.16-he725a3c_1_cpython.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.10-5_cp310.conda
       - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8228510_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda
       - conda: https://prefix.dev/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - pypi: .
       osx-arm64:
       - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.10.0-pyhd8ed1ab_0.conda
@@ -73,21 +73,21 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.124.1-pyha770c72_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libblas-3.9.0-26_osxarm64_openblas.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libcblas-3.9.0-26_osxarm64_openblas.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-19.1.6-ha82da77_1.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-19.1.7-ha82da77_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2
       - conda: https://prefix.dev/conda-forge/osx-arm64/libgfortran-5.0.0-13_2_0_hd922786_3.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libgfortran5-13.2.0-hf226fd6_3.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/liblapack-3.9.0-26_osxarm64_openblas.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.6.3-h39f12f2_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libopenblas-0.3.28-openmp_hf332438_1.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.47.2-h3f77e49_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.48.0-h3f77e49_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.6-hdb05f8b_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.7-hdb05f8b_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/ndindex-1.8-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py310ha1ddda0_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
@@ -102,13 +102,13 @@ environments:
       - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.10.16-h870587a_1_cpython.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python_abi-3.10-5_cp310.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - pypi: .
       win-64:
       - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.10.0-pyhd8ed1ab_0.conda
@@ -121,7 +121,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.124.1-pyha770c72_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda
       - conda: https://prefix.dev/conda-forge/win-64/libblas-3.9.0-26_win64_mkl.conda
@@ -131,8 +131,8 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/libiconv-1.17-hcfcfb64_2.conda
       - conda: https://prefix.dev/conda-forge/win-64/liblapack-3.9.0-26_win64_mkl.conda
       - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.6.3-h2466b09_1.conda
-      - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.47.2-h67fdade_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_8.conda
+      - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.48.0-h67fdade_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda
       - conda: https://prefix.dev/conda-forge/win-64/libxml2-2.13.5-he286e8c_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda
       - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda
@@ -149,14 +149,14 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/python-3.10.16-h37870fc_1_cpython.conda
       - conda: https://prefix.dev/conda-forge/win-64/python_abi-3.10-5_cp310.conda
-      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/win-64/tbb-2021.13.0-h62715c5_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h5226925_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-ha32ba9b_23.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.42.34433-he29a5d6_23.conda
@@ -181,7 +181,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.124.1-pyha770c72_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_2.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libblas-3.9.0-26_linux64_openblas.conda
@@ -197,11 +197,11 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.6.3-hb9d3cd8_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libopenblas-0.3.28-pthreads_h94d23a6_1.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.47.2-hee588c1_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.48.0-hee588c1_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-14.2.0-hc0a3c3a_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_2.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ndindex-1.9.2-py313h536fd9c_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py313hb30382a_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
@@ -213,16 +213,16 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_102_cp313.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_105_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8228510_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda
       - conda: https://prefix.dev/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - pypi: .
       osx-arm64:
       - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.10.0-pyhd8ed1ab_0.conda
@@ -235,11 +235,11 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.124.1-pyha770c72_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libblas-3.9.0-26_osxarm64_openblas.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libcblas-3.9.0-26_osxarm64_openblas.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-19.1.6-ha82da77_1.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-19.1.7-ha82da77_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.6.4-h286801f_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2
       - conda: https://prefix.dev/conda-forge/osx-arm64/libgfortran-5.0.0-13_2_0_hd922786_3.conda
@@ -248,10 +248,10 @@ environments:
       - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.6.3-h39f12f2_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h99b78c6_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libopenblas-0.3.28-openmp_hf332438_1.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.47.2-h3f77e49_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.48.0-h3f77e49_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.6-hdb05f8b_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.7-hdb05f8b_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/ndindex-1.8-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py313ha4a2180_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
@@ -263,16 +263,16 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_102_cp313.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_105_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - pypi: .
       win-64:
       - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.10.0-pyhd8ed1ab_0.conda
@@ -285,7 +285,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.124.1-pyha770c72_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda
       - conda: https://prefix.dev/conda-forge/win-64/libblas-3.9.0-26_win64_mkl.conda
@@ -297,8 +297,8 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/liblapack-3.9.0-26_win64_mkl.conda
       - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.6.3-h2466b09_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.47.2-h67fdade_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_8.conda
+      - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.48.0-h67fdade_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda
       - conda: https://prefix.dev/conda-forge/win-64/libxml2-2.13.5-he286e8c_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda
       - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda
@@ -313,16 +313,16 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_102_cp313.conda
+      - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_105_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/python_abi-3.13-5_cp313.conda
-      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/win-64/tbb-2021.13.0-h62715c5_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h5226925_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-ha32ba9b_23.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.42.34433-he29a5d6_23.conda
@@ -357,22 +357,22 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.6.3-hb9d3cd8_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libopenblas-0.3.28-pthreads_h94d23a6_1.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.47.2-hee588c1_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.48.0-hee588c1_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-14.2.0-hc0a3c3a_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_2.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py313hb30382a_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_102_cp313.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_105_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8228510_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - pypi: .
       osx-arm64:
       - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.10.0-pyhd8ed1ab_0.conda
@@ -383,7 +383,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libblas-3.9.0-26_osxarm64_openblas.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libcblas-3.9.0-26_osxarm64_openblas.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-19.1.6-ha82da77_1.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-19.1.7-ha82da77_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.6.4-h286801f_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2
       - conda: https://prefix.dev/conda-forge/osx-arm64/libgfortran-5.0.0-13_2_0_hd922786_3.conda
@@ -392,21 +392,21 @@ environments:
       - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.6.3-h39f12f2_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h99b78c6_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libopenblas-0.3.28-openmp_hf332438_1.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.47.2-h3f77e49_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.48.0-h3f77e49_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.6-hdb05f8b_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.7-hdb05f8b_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_2.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py313ha4a2180_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_102_cp313.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_105_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - pypi: .
       win-64:
       - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.10.0-pyhd8ed1ab_0.conda
@@ -425,8 +425,8 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/liblapack-3.9.0-26_win64_mkl.conda
       - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.6.3-h2466b09_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.47.2-h67fdade_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_8.conda
+      - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.48.0-h67fdade_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda
       - conda: https://prefix.dev/conda-forge/win-64/libxml2-2.13.5-he286e8c_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda
       - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda
@@ -434,13 +434,13 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pint-0.24.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_102_cp313.conda
+      - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_105_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/tbb-2021.13.0-h62715c5_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h5226925_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-ha32ba9b_23.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.42.34433-he29a5d6_23.conda
@@ -472,7 +472,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/filelock-3.16.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.124.1-pyha770c72_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/ipython-8.31.0-pyh707e725_0.conda
@@ -491,12 +491,12 @@ environments:
       - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.6.3-hb9d3cd8_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libopenblas-0.3.28-pthreads_h94d23a6_1.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.47.2-hee588c1_0.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.48.0-hee588c1_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-14.2.0-hc0a3c3a_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_2.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ndindex-1.9.2-py313h536fd9c_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.1-py313hb30382a_0.conda
@@ -513,16 +513,16 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
-      - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_102_cp313.conda
+      - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_105_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/linux-64/pyyaml-6.0.2-py313h536fd9c_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8228510_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda
@@ -530,9 +530,9 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - conda: https://prefix.dev/conda-forge/linux-64/ukkonen-1.0.1-py313h33d0bda_5.conda
-      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.29.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2
       - pypi: .
@@ -554,14 +554,14 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/filelock-3.16.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.124.1-pyha770c72_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/ipython-8.31.0-pyh707e725_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libblas-3.9.0-26_osxarm64_openblas.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libcblas-3.9.0-26_osxarm64_openblas.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-19.1.6-ha82da77_1.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-19.1.7-ha82da77_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.6.4-h286801f_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2
       - conda: https://prefix.dev/conda-forge/osx-arm64/libgfortran-5.0.0-13_2_0_hd922786_3.conda
@@ -570,11 +570,11 @@ environments:
       - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.6.3-h39f12f2_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h99b78c6_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libopenblas-0.3.28-openmp_hf332438_1.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.47.2-h3f77e49_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.48.0-h3f77e49_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.6-hdb05f8b_0.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.7-hdb05f8b_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/ndindex-1.8-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.1-py313ha4a2180_0.conda
@@ -591,16 +591,16 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
-      - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_102_cp313.conda
+      - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_105_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/pyyaml-6.0.2-py313h20a7fcf_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda
@@ -608,9 +608,9 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/ukkonen-1.0.1-py313hf9c7212_5.conda
-      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.29.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2
       - pypi: .
@@ -632,7 +632,7 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/filelock-3.16.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexcache-0.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/flexparser-0.4-pyhd8ed1ab_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.124.1-pyha770c72_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda
@@ -647,8 +647,8 @@ environments:
       - conda: https://prefix.dev/conda-forge/win-64/liblapack-3.9.0-26_win64_mkl.conda
       - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.6.3-h2466b09_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.47.2-h67fdade_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_8.conda
+      - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.48.0-h67fdade_0.conda
+      - conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda
       - conda: https://prefix.dev/conda-forge/win-64/libxml2-2.13.5-he286e8c_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda
       - conda: https://prefix.dev/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda
@@ -667,15 +667,15 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/prompt-toolkit-3.0.48-pyha770c72_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-json-report-1.5.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/pytest-metadata-3.1.1-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/pytest-subtests-0.14.1-pyhd8ed1ab_0.conda
-      - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_102_cp313.conda
+      - conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_105_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/python_abi-3.13-5_cp313.conda
       - conda: https://prefix.dev/conda-forge/win-64/pyyaml-6.0.2-py313ha7868ed_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
+      - conda: https://prefix.dev/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
       - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2
       - conda: https://prefix.dev/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/tbb-2021.13.0-h62715c5_1.conda
@@ -684,12 +684,12 @@ environments:
       - conda: https://prefix.dev/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_1.conda
-      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/ukkonen-1.0.1-py313h1ec8472_5.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-ha32ba9b_23.conda
       - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.42.34433-he29a5d6_23.conda
-      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
+      - conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.29.1-pyhd8ed1ab_0.conda
       - conda: https://prefix.dev/conda-forge/win-64/vs2015_runtime-14.42.34433-hdffcdeb_23.conda
       - conda: https://prefix.dev/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_1.conda
       - conda: https://prefix.dev/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2
@@ -990,9 +990,9 @@ packages:
   - pkg:pypi/flexparser?source=hash-mapping
   size: 28686
   timestamp: 1733663636245
-- conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.123.2-pyha770c72_0.conda
-  sha256: cb9584d6b69edef23a4e5fedde8f77f12dec870b71d1ff4051b562b182697468
-  md5: a3f74b10f4f6be84de2aeedd8b4da745
+- conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.124.1-pyha770c72_0.conda
+  sha256: 5ae4e5ddd779db2f453877f7dc5c941a4c6f1a0620f045920ba525597a2579a7
+  md5: d05625ce1c3445c4c21a778036173107
   depends:
   - attrs >=22.2.0
   - click >=7.0
@@ -1004,8 +1004,8 @@ packages:
   license_family: MOZILLA
   purls:
   - pkg:pypi/hypothesis?source=hash-mapping
-  size: 341990
-  timestamp: 1735341651189
+  size: 344304
+  timestamp: 1737209246416
 - conda: https://prefix.dev/conda-forge/noarch/identify-2.6.5-pyhd8ed1ab_0.conda
   sha256: e8ea11b8e39a98a9c34efb5c21c3fca718e31e1f41fd9ae5f6918b8eb402da59
   md5: c1b0f663ff141265d1be1242259063f0
@@ -1201,16 +1201,16 @@ packages:
   purls: []
   size: 3732146
   timestamp: 1734432785653
-- conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-19.1.6-ha82da77_1.conda
-  sha256: 2b2443404503cd862385fd2f2a2c73f9624686fd1e5a45050b4034cfc06904ec
-  md5: ce5252d8db110cdb4ae4173d0a63c7c5
+- conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-19.1.7-ha82da77_0.conda
+  sha256: 776092346da87a2a23502e14d91eb0c32699c4a1522b7331537bd1c3751dcff5
+  md5: 5b3e1610ff8bd5443476b91d618f5b77
   depends:
   - __osx >=11.0
   license: Apache-2.0 WITH LLVM-exception
   license_family: Apache
   purls: []
-  size: 520992
-  timestamp: 1734494699681
+  size: 523505
+  timestamp: 1736877862502
 - conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.6.4-h5888daf_0.conda
   sha256: 56541b98447b58e52d824bd59d6382d609e11de1f8adf20b23143e353d2b8d26
   md5: db833e03127376d461e1e13e76f09b6c
@@ -1532,38 +1532,38 @@ packages:
   purls: []
   size: 4165774
   timestamp: 1730772154295
-- conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.47.2-hee588c1_0.conda
-  sha256: 48af21ebc2cbf358976f1e0f4a0ab9e91dfc83d0ef337cf3837c6f5bc22fb352
-  md5: b58da17db24b6e08bcbf8fed2fb8c915
+- conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.48.0-hee588c1_0.conda
+  sha256: 7bb84f44e1bd756da4a3d0d43308324a5533e6ba9f4772475884bce44d405064
+  md5: 84bd1c9a82b455e7a2f390375fb38f90
   depends:
   - __glibc >=2.17,<3.0.a0
   - libgcc >=13
   - libzlib >=1.3.1,<2.0a0
   license: Unlicense
   purls: []
-  size: 873551
-  timestamp: 1733761824646
-- conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.47.2-h3f77e49_0.conda
-  sha256: f192f3c8973de9ec4c214990715f13b781965247a5cedf9162e7f9e699cfc3c4
-  md5: 122d6f29470f1a991e85608e77e56a8a
+  size: 876582
+  timestamp: 1737123945341
+- conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.48.0-h3f77e49_0.conda
+  sha256: b31169cf0ca7b6835baca4ab92d6cf2eee83b1a12a11b72f39521e8baf4d6acb
+  md5: 714719df4f49e30f9728956f240846ca
   depends:
   - __osx >=11.0
   - libzlib >=1.3.1,<2.0a0
   license: Unlicense
   purls: []
-  size: 850553
-  timestamp: 1733762057506
-- conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.47.2-h67fdade_0.conda
-  sha256: ecfc0182c3b2e63c870581be1fa0e4dbdfec70d2011cb4f5bde416ece26c41df
-  md5: ff00095330e0d35a16bd3bdbd1a2d3e7
+  size: 853163
+  timestamp: 1737124192432
+- conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.48.0-h67fdade_0.conda
+  sha256: 2868c0df07b6d0682c9f3709523b6f3f3577f18e0d6f0e31022b48e6d0059f74
+  md5: f4268a291ae1f885d4b96add05865cc8
   depends:
   - ucrt >=10.0.20348.0
   - vc >=14.2,<15
   - vc14_runtime >=14.29.30139
   license: Unlicense
   purls: []
-  size: 891292
-  timestamp: 1733762116902
+  size: 897200
+  timestamp: 1737124291192
 - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-14.2.0-hc0a3c3a_1.conda
   sha256: 4661af0eb9bdcbb5fb33e5d0023b001ad4be828fccdcc56500059d56f9869462
   md5: 234a5554c53625688d51062645337328
@@ -1584,9 +1584,9 @@ packages:
   purls: []
   size: 33601
   timestamp: 1680112270483
-- conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_8.conda
-  sha256: 6d5e158813ab8d553fbb0fedd0abe7bf92970b0be3a9ddf12da0f6cbad78f506
-  md5: 03cccbba200ee0523bde1f3dad60b1f3
+- conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda
+  sha256: 373f2973b8a358528b22be5e8d84322c165b4c5577d24d94fd67ad1bb0a0f261
+  md5: 08bfa5da6e242025304b206d152479ef
   depends:
   - ucrt
   constrains:
@@ -1594,8 +1594,8 @@ packages:
   - msys2-conda-epoch <0.0a0
   license: MIT AND BSD-3-Clause-Clear
   purls: []
-  size: 35433
-  timestamp: 1724681489463
+  size: 35794
+  timestamp: 1737099561703
 - conda: https://prefix.dev/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda
   sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c
   md5: 5aa797f8787fe7a17d1b0821485b5adc
@@ -1658,18 +1658,18 @@ packages:
   purls: []
   size: 55476
   timestamp: 1727963768015
-- conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.6-hdb05f8b_0.conda
-  sha256: a0f3e9139ab16f0a67b9d2bbabc15b78977168f4a5b5503fed4962dcb9a96102
-  md5: 34fdeffa0555a1a56f38839415cc066c
+- conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-19.1.7-hdb05f8b_0.conda
+  sha256: b92a669f2059874ebdcb69041b6c243d68ffc3fb356ac1339cec44aeb27245d7
+  md5: c4d54bfd3817313ce758aa76283b118d
   depends:
   - __osx >=11.0
   constrains:
-  - openmp 19.1.6|19.1.6.*
+  - openmp 19.1.7|19.1.7.*
   license: Apache-2.0 WITH LLVM-exception
   license_family: APACHE
   purls: []
-  size: 281251
-  timestamp: 1734520462311
+  size: 280830
+  timestamp: 1736986295869
 - conda: https://prefix.dev/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda
   sha256: 69b7dc7131703d3d60da9b0faa6dd8acbf6f6c396224cf6aef3e855b8c0c41c6
   md5: af6ab708897df59bd6e7283ceab1b56b
@@ -1693,25 +1693,25 @@ packages:
   purls: []
   size: 103106385
   timestamp: 1730232843711
-- conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda
-  sha256: 6a1d5d8634c1a07913f1c525db6455918cbc589d745fac46d9d6e30340c8731a
-  md5: 70caf8bb6cf39a0b6b7efc885f51c0fe
+- conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_2.conda
+  sha256: 17fe6afd8a00446010220d52256bd222b1e4fcb93bd587e7784b03219f3dc358
+  md5: 04b34b9a40cdc48cfdab261ab176ff74
   depends:
   - __glibc >=2.17,<3.0.a0
-  - libgcc-ng >=12
+  - libgcc >=13
   license: X11 AND BSD-3-Clause
   purls: []
-  size: 889086
-  timestamp: 1724658547447
-- conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda
-  sha256: 27d0b9ff78ad46e1f3a6c96c479ab44beda5f96def88e2fe626e0a49429d8afc
-  md5: cb2b0ea909b97b3d70cd3921d1445e1a
+  size: 894452
+  timestamp: 1736683239706
+- conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_2.conda
+  sha256: b45c73348ec9841d5c893acc2e97adff24127548fe8c786109d03c41ed564e91
+  md5: f6f7c5b7d0983be186c46c4f6f8f9af8
   depends:
   - __osx >=11.0
   license: X11 AND BSD-3-Clause
   purls: []
-  size: 802321
-  timestamp: 1724658775723
+  size: 796754
+  timestamp: 1736683572099
 - conda: https://prefix.dev/conda-forge/linux-64/ndindex-1.9.2-py310ha75aee5_1.conda
   sha256: c76069d91b72b0f3c860f19d97d788bb3647262202925901cce0f9f3b1be15ef
   md5: 45bd8358c819898e546588bd38368162
@@ -2100,17 +2100,17 @@ packages:
   purls: []
   size: 110100
   timestamp: 1733195786147
-- conda: https://prefix.dev/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_1.conda
-  sha256: 0d6133545f268b2b89c2617c196fc791f365b538d4057ecd636d658c3b1e885d
-  md5: b38dc0206e2a530e5c2cf11dc086b31a
+- conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda
+  sha256: 28a3e3161390a9d23bc02b4419448f8d27679d9e2c250e29849e37749c8de86b
+  md5: 232fb4577b6687b2d503ef8e254270c9
   depends:
   - python >=3.9
   license: BSD-2-Clause
   license_family: BSD
   purls:
   - pkg:pypi/pygments?source=hash-mapping
-  size: 876700
-  timestamp: 1733221731178
+  size: 888600
+  timestamp: 1736243563082
 - conda: https://prefix.dev/conda-forge/noarch/pytest-8.3.4-pyhd8ed1ab_1.conda
   sha256: 75245ca9d0cbd6d38bb45ec02430189a9d4c21c055c5259739d738a2298d61b3
   md5: 799ed216dc6af62520f32aa39bc1c2bb
@@ -2195,10 +2195,10 @@ packages:
   purls: []
   size: 25199631
   timestamp: 1733409331823
-- conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_102_cp313.conda
-  build_number: 102
-  sha256: b10f25c5edc203d15b3f54861bec4868b8200ebc16c8cbc82202e4c8da2b183e
-  md5: 6e7535f1d1faf524e9210d2689b3149b
+- conda: https://prefix.dev/conda-forge/linux-64/python-3.13.1-ha99a958_105_cp313.conda
+  build_number: 105
+  sha256: d3eb7d0820cf0189103bba1e60e242ffc15fd2f727640ac3a10394b27adf3cca
+  md5: 34945787453ee52a8f8271c1d19af1e8
   depends:
   - __glibc >=2.17,<3.0.a0
   - bzip2 >=1.0.8,<2.0a0
@@ -2208,7 +2208,7 @@ packages:
   - libgcc >=13
   - liblzma >=5.6.3,<6.0a0
   - libmpdec >=4.0.0,<5.0a0
-  - libsqlite >=3.47.0,<4.0a0
+  - libsqlite >=3.47.2,<4.0a0
   - libuuid >=2.38.1,<3.0a0
   - libzlib >=1.3.1,<2.0a0
   - ncurses >=6.5,<7.0a0
@@ -2219,8 +2219,8 @@ packages:
   - tzdata
   license: Python-2.0
   purls: []
-  size: 33263183
-  timestamp: 1733436074842
+  size: 33169840
+  timestamp: 1736763984540
 - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.10.16-h870587a_1_cpython.conda
   build_number: 1
   sha256: cd617b15712c4f9316b22c75459311ed106ccb0659c0bf36e281a9162b4e2d95
@@ -2243,10 +2243,10 @@ packages:
   purls: []
   size: 12372048
   timestamp: 1733408850559
-- conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_102_cp313.conda
-  build_number: 102
-  sha256: 0379adf6bb35ca47036860983701e8f6fae89c028d422f2b9439f3110893bc24
-  md5: 8c65c1dfc98312ef8666dbb7c7fc47ca
+- conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.1-h4f43103_105_cp313.conda
+  build_number: 105
+  sha256: 7d27cc8ef214abbdf7dd8a5d473e744f4bd9beb7293214a73c58e4895c2830b8
+  md5: 11d916b508764b7d881dd5c75d222d6e
   depends:
   - __osx >=11.0
   - bzip2 >=1.0.8,<2.0a0
@@ -2254,7 +2254,7 @@ packages:
   - libffi >=3.4,<4.0a0
   - liblzma >=5.6.3,<6.0a0
   - libmpdec >=4.0.0,<5.0a0
-  - libsqlite >=3.47.0,<4.0a0
+  - libsqlite >=3.47.2,<4.0a0
   - libzlib >=1.3.1,<2.0a0
   - ncurses >=6.5,<7.0a0
   - openssl >=3.4.0,<4.0a0
@@ -2264,8 +2264,8 @@ packages:
   - tzdata
   license: Python-2.0
   purls: []
-  size: 12905237
-  timestamp: 1733433280639
+  size: 12919840
+  timestamp: 1736761931666
 - conda: https://prefix.dev/conda-forge/win-64/python-3.10.16-h37870fc_1_cpython.conda
   build_number: 1
   sha256: 3392db6a7a90864d3fd1ce281859a49e27ee68121b63eece2ae6f1dbb2a8aaf1
@@ -2288,17 +2288,17 @@ packages:
   purls: []
   size: 16061214
   timestamp: 1733408154785
-- conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_102_cp313.conda
-  build_number: 102
-  sha256: ee41eda85ebc3a257a3b21a76d255d986b08a285d891e418cbfb70113ee14684
-  md5: 70568ba8bbd5f0c7b830e690775eb8b7
+- conda: https://prefix.dev/conda-forge/win-64/python-3.13.1-h071d269_105_cp313.conda
+  build_number: 105
+  sha256: de3bb832ff3982c993c6af15e6c45bb647159f25329caceed6f73fd4769c7628
+  md5: 3ddb0531ecfb2e7274d471203e053d78
   depends:
   - bzip2 >=1.0.8,<2.0a0
   - libexpat >=2.6.4,<3.0a0
   - libffi >=3.4,<4.0a0
   - liblzma >=5.6.3,<6.0a0
   - libmpdec >=4.0.0,<5.0a0
-  - libsqlite >=3.47.0,<4.0a0
+  - libsqlite >=3.47.2,<4.0a0
   - libzlib >=1.3.1,<2.0a0
   - openssl >=3.4.0,<4.0a0
   - python_abi 3.13.* *_cp313
@@ -2309,8 +2309,8 @@ packages:
   - vc14_runtime >=14.29.30139
   license: Python-2.0
   purls: []
-  size: 16753813
-  timestamp: 1733433028707
+  size: 16778758
+  timestamp: 1736761341620
 - conda: https://prefix.dev/conda-forge/linux-64/python_abi-3.10-5_cp310.conda
   build_number: 5
   sha256: 074d2f0b31f0333b7e553042b17ea54714b74263f8adda9a68a4bd8c7e219971
@@ -2444,17 +2444,17 @@ packages:
   purls: []
   size: 250351
   timestamp: 1679532511311
-- conda: https://prefix.dev/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_1.conda
-  sha256: abb12e1dd515b13660aacb5d0fd43835bc2186cab472df25b7716cd65e095111
-  md5: fc80f7995e396cbaeabd23cf46c413dc
+- conda: https://prefix.dev/conda-forge/noarch/setuptools-75.8.0-pyhff2d567_0.conda
+  sha256: e0778e4f276e9a81b51c56f51ec22a27b4d8fc955abc0be77ad09ca9bea06bb9
+  md5: 8f28e299c11afdd79e0ec1e279dcdc52
   depends:
   - python >=3.9
   license: MIT
   license_family: MIT
   purls:
   - pkg:pypi/setuptools?source=hash-mapping
-  size: 774252
-  timestamp: 1732632769210
+  size: 775598
+  timestamp: 1736512753595
 - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2
   sha256: 0cea408397d50c2afb2d25e987ebac4546ae11e549d65b1403d80dc368dfaaa6
   md5: 6d6552722448103793743dabfbda532d
@@ -2570,13 +2570,13 @@ packages:
   - pkg:pypi/typing-extensions?source=hash-mapping
   size: 39637
   timestamp: 1733188758212
-- conda: https://prefix.dev/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda
-  sha256: 4fde5c3008bf5d2db82f2b50204464314cc3c91c1d953652f7bd01d9e52aefdf
-  md5: 8ac3367aafb1cc0a068483c580af8015
+- conda: https://prefix.dev/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda
+  sha256: c4b1ae8a2931fe9b274c44af29c5475a85b37693999f8c792dad0f8c6734b1de
+  md5: dbcace4706afdfb7eb891f7b37d07c04
   license: LicenseRef-Public-Domain
   purls: []
-  size: 122354
-  timestamp: 1728047496079
+  size: 122921
+  timestamp: 1737119101255
 - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda
   sha256: db8dead3dd30fb1a032737554ce91e2819b43496a0db09927edf01c32b577450
   md5: 6797b005cd0f439c4c5c9ac565783700
@@ -2658,9 +2658,9 @@ packages:
   purls: []
   size: 754247
   timestamp: 1731710681163
-- conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.28.1-pyhd8ed1ab_0.conda
-  sha256: c8bde4547ddbd21ea89e483a7c65d8a5e442c0db494b0b977e389b75b9d03d62
-  md5: 680b1c287b10cefc8bda0530b217229f
+- conda: https://prefix.dev/conda-forge/noarch/virtualenv-20.29.1-pyhd8ed1ab_0.conda
+  sha256: f09a9f2034669762ae875858253d472588f03689843e5f0b8ddc5cc48a1d0e50
+  md5: de06336c9833cffd2a4bd6f27c4cf8ea
   depends:
   - distlib >=0.3.7,<1
   - filelock >=3.12.2,<4
@@ -2669,9 +2669,9 @@ packages:
   license: MIT
   license_family: MIT
   purls:
-  - pkg:pypi/virtualenv?source=hash-mapping
-  size: 3350367
-  timestamp: 1735929107438
+  - pkg:pypi/virtualenv?source=compressed-mapping
+  size: 3501167
+  timestamp: 1737145224475
 - conda: https://prefix.dev/conda-forge/win-64/vs2015_runtime-14.42.34433-hdffcdeb_23.conda
   sha256: 568ce8151eaae256f1cef752fc78651ad7a86ff05153cc7a4740b52ae6536118
   md5: 5c176975ca2b8366abad3c97b3cd1e83
diff --git a/tests/test_array.py b/tests/test_array.py
index 5ae1308..2d4c915 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -1,5 +1,3 @@
-from __future__ import annotations
-
 import copy
 import operator as op
 
@@ -14,7 +12,7 @@
 pxp = pint_array.pint_namespace(xp)
 
 
-class TestNumPyMethods:
+class TestArrayMethods:
     @classmethod
     def setup_class(cls):
         from pint import _DEFAULT_REGISTRY
@@ -54,9 +52,7 @@ def assertNDArrayEqual(self, actual, desired):
         assert not isinstance(desired, self.Q_)
 
 
-class TestNumPyArrayCreation(TestNumPyMethods):
-    # https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html
-
+class TestArrayCreation(TestArrayMethods):
     @pytest.mark.xfail(reason="Scalar argument issue ")
     def test_ones_like(self):
         self.assertNDArrayEqual(pxp.ones_like(self.q), pxp.asarray([[1, 1], [1, 1]]))
@@ -79,7 +75,7 @@ def test_full_like(self):
         self.assertNDArrayEqual(pxp.full_like(self.q, 2), pxp.asarray([[2, 2], [2, 2]]))
 
 
-class TestNumPyArrayManipulation(TestNumPyMethods):
+class TestArrayManipulation(TestArrayMethods):
     # Changing array shape
 
     def test_reshape(self):
@@ -171,9 +167,7 @@ def test_roll(self):
         )
 
 
-class TestNumPyMathematicalFunctions(TestNumPyMethods):
-    # https://www.numpy.org/devdocs/reference/routines.math.html
-
+class TestArrayMathematicalFunctions(TestArrayMethods):
     def test_prod_numpy_func(self):
         axis = 0
 
@@ -251,7 +245,7 @@ def test_exponentiation_array_exp_2(self):
             op.ipow(arr_cp, q_cp)
 
 
-class TestNumPyUnclassified(TestNumPyMethods):
+class TestArrayUnclassified(TestArrayMethods):
     def test_repeat(self):
         helpers.assert_quantity_equal(
             pxp.repeat(self.q, 2), [1, 1, 2, 2, 3, 3, 4, 4] * self.ureg.m
@@ -325,9 +319,7 @@ def test_clip_numpy_func(self):
 
     def test_round_numpy_func(self):
         helpers.assert_quantity_equal(
-            pxp.round(
-                102.75 * self.ureg.m,
-            ),
+            pxp.round(102.75 * self.ureg.m),
             103 * self.ureg.m,
         )
 
@@ -364,9 +356,7 @@ def test_std_numpy_func(self):
     def test_conj(self):
         arr = pxp.asarray(self.q, dtype=pxp.complex64) * (1 + 1j)
         helpers.assert_quantity_equal(pxp.conj(arr), arr * (1 - 1j))
-        # helpers.assert_quantity_equal(
-        #     (self.q * (1 + 1j)).conjugate(), self.q * (1 - 1j)
-        # )
+        helpers.assert_quantity_equal((arr * (1 + 1j)).conj(), arr * (1 - 1j))
 
     def test_getitem(self):
         with pytest.raises(IndexError):
@@ -410,7 +400,6 @@ def test_setitem(self):
         helpers.assert_quantity_equal(q, [0.001, 1, 2, 3] * self.ureg.m / self.ureg.mm)
 
     def test_reversible_op(self):
-        """ """
         q = pxp.asarray(self.q, dtype=pxp.float64)
         x = xp.asarray(self.q.magnitude, dtype=xp.float64)
         u = pxp.asarray(pxp.ones(x.shape), dtype=pxp.float64)
@@ -460,10 +449,10 @@ def test_meshgrid_numpy_func(self):
         helpers.assert_quantity_equal(yy, [[0, 0], [50, 50], [100, 100]] * self.ureg.mm)
 
     def test_comparisons(self):
-        # self.assertNDArrayEqual(
-        #     pxp.asarray(self.q) > 2 * self.ureg.m,
-        #     xp.asarray([[False, False], [True, True]])
-        # )
+        self.assertNDArrayEqual(
+            pxp.asarray(self.q) > 2 * self.ureg.m,
+            xp.asarray([[False, False], [True, True]])
+        )
         self.assertNDArrayEqual(
             pxp.asarray(self.q) < 2 * self.ureg.m,
             xp.asarray([[True, False], [False, False]]),