diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c52d210..75bfa62 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,23 +1,21 @@ exclude: '^pint/_vendor' repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace -- repo: https://github.com/psf/black - rev: 23.7.0 - hooks: - - id: black - - id: black-jupyter -- repo: https://github.com/charliermarsh/ruff-pre-commit - rev: 'v0.0.282' +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.1.7 hooks: - id: ruff - args: ["--fix"] + args: ["--fix", "--show-fixes"] + types_or: [ python, pyi, jupyter ] + - id: ruff-format + types_or: [ python, pyi, jupyter ] - repo: https://github.com/executablebooks/mdformat - rev: 0.7.16 + rev: 0.7.17 hooks: - id: mdformat additional_dependencies: @@ -28,15 +26,3 @@ repos: hooks: - id: nbstripout args: [--extra-keys=metadata.kernelspec metadata.language_info.version] -- repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.8.0" - hooks: - - id: mypy - verbose: true - args: ["--ignore-missing-imports", "--show-error-codes"] - additional_dependencies: [ - "types-requests", - "pandas-stubs", - "pint", - "matplotlib-stubs", - ] diff --git a/CHANGES b/CHANGES index d1f4a54..037310c 100644 --- a/CHANGES +++ b/CHANGES @@ -5,7 +5,7 @@ pint-pandas Changelog 0.7 (unreleased) -------------------- -- Nothing added yet +- Added `__array_function__` support for numpy fuctions like clip. 0.6.2 (2024-07-29) diff --git a/pint_pandas/pint_array.py b/pint_pandas/pint_array.py index 93c787e..df5ed65 100644 --- a/pint_pandas/pint_array.py +++ b/pint_pandas/pint_array.py @@ -327,6 +327,11 @@ def __setstate__(self, dct): self.__dict__.update(dct) self._Q = self.dtype.ureg.Quantity + def __array_function__(self, func, types, args, kwargs): + args = convert_np_inputs(args) + result = func(*args, **kwargs) + return self._convert_np_result(result) + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): out = kwargs.get("out", ()) for x in inputs + out: @@ -346,6 +351,8 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): def _convert_np_result(self, result): if isinstance(result, _Quantity) and is_list_like(result.m): + if hasattr(result, "ndim") and result.ndim >= 2: + raise ValueError("PintArrays may only be 1D, check axis arguement") return PintArray.from_1darray_quantity(result) elif isinstance(result, _Quantity): return result @@ -356,6 +363,8 @@ def _convert_np_result(self, result): isinstance(item, _Quantity) for item in result ): return PintArray._from_sequence(result) + elif isinstance(result, np.ndarray): + return result elif result is None: # no return value return result @@ -1172,8 +1181,9 @@ def __init__(self, pandas_obj): def _validate(obj): if not is_pint_type(obj): raise AttributeError( - "Cannot use 'pint' accessor on objects of " - "dtype '{}'.".format(obj.dtype) + "Cannot use 'pint' accessor on objects of " "dtype '{}'.".format( + obj.dtype + ) ) @staticmethod diff --git a/pint_pandas/testsuite/test_issues.py b/pint_pandas/testsuite/test_issues.py index 74f26eb..3ea07eb 100644 --- a/pint_pandas/testsuite/test_issues.py +++ b/pint_pandas/testsuite/test_issues.py @@ -311,3 +311,16 @@ def test_issue246(self): # now an operation where each cell is independent from each other df.apply(lambda x: x * 2, axis=1) + + +class TestIssue255(BaseExtensionTests): + def test_issue255(self): + a = np.r_[1, 2, np.nan, 4, 10] + pa = PintArray.from_1darray_quantity(a * ureg.m) + + result = np.clip(pa, 3 * ureg.m, 5 * ureg.m) + + e = np.clip(a, 3, 5) + expected = PintArray.from_1darray_quantity(e * ureg.m) + + tm.assert_equal(result, expected) diff --git a/pint_pandas/testsuite/test_pandas_extensiontests.py b/pint_pandas/testsuite/test_pandas_extensiontests.py index 7d5ba04..163e855 100644 --- a/pint_pandas/testsuite/test_pandas_extensiontests.py +++ b/pint_pandas/testsuite/test_pandas_extensiontests.py @@ -603,3 +603,11 @@ def test_EA_types(self, engine, data, request): @pytest.mark.skip("TODO: fix this test") def test_array_interface_copy(self, data): pass + + @pytest.mark.skip(reason="not implemented in pint") + def test_repeat(self): + pass + + @pytest.mark.skip(reason="not implemented in pint") + def test_repeat_raises(self): + pass diff --git a/pyproject.toml b/pyproject.toml index 4b4ab85..c44f88e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,6 +74,7 @@ ignore = [ "E731", # line break before binary operator # "W503" + "F811", ] extend-exclude = ["build"] line-length=88