Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-unyt for openSUSE:Factory 
checked in at 2024-07-11 20:32:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-unyt (Old)
 and      /work/SRC/openSUSE:Factory/.python-unyt.new.17339 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-unyt"

Thu Jul 11 20:32:53 2024 rev:7 rq:1186726 version:3.0.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-unyt/python-unyt.changes  2024-03-17 
22:16:31.285526201 +0100
+++ /work/SRC/openSUSE:Factory/.python-unyt.new.17339/python-unyt.changes       
2024-07-11 20:33:32.573663889 +0200
@@ -1,0 +2,8 @@
+Thu Jul 11 02:42:33 UTC 2024 - Steve Kowalik <steven.kowa...@suse.com>
+
+- Update to 3.0.3:
+  * BUG: fix signature incompatibilities in NEP 18 wrapped functions
+  * BUG: fix an incompatibility with sympy 1.13.0rc1
+- Restrict numpy to < 2.
+
+-------------------------------------------------------------------

Old:
----
  unyt-3.0.2.tar.gz

New:
----
  unyt-3.0.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-unyt.spec ++++++
--- /var/tmp/diff_new_pack.h4XyE8/_old  2024-07-11 20:33:33.141684645 +0200
+++ /var/tmp/diff_new_pack.h4XyE8/_new  2024-07-11 20:33:33.145684792 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-unyt
-Version:        3.0.2
+Version:        3.0.3
 Release:        0
 Summary:        A package for handling numpy arrays with units
 License:        BSD-3-Clause
@@ -33,12 +33,12 @@
 # SECTION test
 BuildRequires:  %{python_module dask-array}
 BuildRequires:  %{python_module dask-diagnostics}
-BuildRequires:  %{python_module numpy >= 1.19.3}
+BuildRequires:  %{python_module numpy >= 1.19.3 with %python-numpy < 2}
 BuildRequires:  %{python_module packaging >= 20.9}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module sympy >= 1.7}
 # /SECTION
-Requires:       python-numpy >= 1.19.3
+Requires:       (python-numpy >= 1.19.3 with python-numpy < 2)
 Requires:       python-packaging > 20.9
 Requires:       python-sympy >= 1.7
 BuildArch:      noarch

++++++ unyt-3.0.2.tar.gz -> unyt-3.0.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/.github/workflows/ci.yml 
new/unyt-3.0.3/.github/workflows/ci.yml
--- old/unyt-3.0.2/.github/workflows/ci.yml     2024-01-28 09:32:56.000000000 
+0100
+++ new/unyt-3.0.3/.github/workflows/ci.yml     2024-07-01 19:41:17.000000000 
+0200
@@ -24,7 +24,8 @@
           - '3.12'
         # Test all on ubuntu, test ends on macos and windows
         include:
-          - os: macos-latest
+          - os: macos-12
+            # pin macos-12 (x86) because Python 3.9 is broken in the arm64 
image
             python-version: '3.9'
           - os: windows-latest
             python-version: '3.9'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/.pre-commit-config.yaml 
new/unyt-3.0.3/.pre-commit-config.yaml
--- old/unyt-3.0.2/.pre-commit-config.yaml      2024-02-24 15:11:41.000000000 
+0100
+++ new/unyt-3.0.3/.pre-commit-config.yaml      2024-07-02 15:31:26.000000000 
+0200
@@ -10,7 +10,7 @@
 
 repos:
 -   repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.5.0
+    rev: v4.6.0
     hooks:
     - id: trailing-whitespace
     - id: end-of-file-fixer
@@ -21,18 +21,18 @@
     - id: check-toml
 
 -   repo: https://github.com/psf/black
-    rev: 24.1.1
+    rev: 24.4.2
     hooks:
     - id: black
 
 -   repo: https://github.com/adamchainz/blacken-docs
-    rev: 1.16.0
+    rev: 1.18.0
     hooks:
     -   id: blacken-docs
         additional_dependencies: [black==24.1.1]
 
 - repo: https://github.com/astral-sh/ruff-pre-commit
-  rev: v0.2.0
+  rev: v0.5.0
   hooks:
   - id: ruff
     args: [--fix, --show-fixes]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/CONTRIBUTING.rst 
new/unyt-3.0.3/CONTRIBUTING.rst
--- old/unyt-3.0.2/CONTRIBUTING.rst     2024-01-27 13:22:26.000000000 +0100
+++ new/unyt-3.0.3/CONTRIBUTING.rst     2024-07-01 19:41:17.000000000 +0200
@@ -106,7 +106,7 @@
 
     $ cd unyt/
     $ pyenv local 3.10
-    $ python setup.py develop
+    $ python -m pip install -e
 
 5. Create a branch for local development::
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/HISTORY.rst new/unyt-3.0.3/HISTORY.rst
--- old/unyt-3.0.2/HISTORY.rst  2024-03-13 07:25:16.000000000 +0100
+++ new/unyt-3.0.3/HISTORY.rst  2024-07-02 15:38:31.000000000 +0200
@@ -2,6 +2,35 @@
 History
 =======
 
+3.0.3 (2024-07-02)
+------------------
+
+This new bugfix release of ``unyt`` fixes bugs discovered since the v3.0.2 
release.
+
+* Fix defects when running test suite in isolation from the project's pytest
+  configuration (`PR #495 <https://github.com/yt-project/unyt/pull/495>`_). 
Thank you
+  to Clément Robert (@neutrinoceros on GitHub) for the contribution.
+
+* Drop test case for unpickling old pickle files as too sensitive to upstream 
changes
+  (`PR #498 <https://github.com/yt-project/unyt/pull/498>`_). Thank you to 
Clément
+  Robert (@neutrinoceros on GitHub) for the contribution.
+
+* Fix signature incompatibilities in nep 18 wrapped functions (`PR #500
+  <https://github.com/yt-project/unyt/pull/500>`_). Thank you to Clément 
Robert
+  (@neutrinoceros on GitHub) for the contribution.
+
+* Fix an incompatibility with sympy 1.13.0rc1 (`PR #504
+  <https://github.com/yt-project/unyt/pull/504>`_). Thank you to Clément 
Robert
+  (@neutrinoceros on GitHub) for the contribution.
+
+* Adjust doctests to changes in array repr from numpy 2.0  (`PR #506
+  <https://github.com/yt-project/unyt/pull/506>`_). Thank you to Clément 
Robert
+  (@neutrinoceros on GitHub) for the contribution.
+
+* TST: declare np.unstack as subclass-safe (fix incompatibility with Numpy 2.1)
+  (`PR #509 <https://github.com/yt-project/unyt/pull/509>`_). Thank you to
+  Clément Robert (@neutrinoceros on GitHub) for the contribution.
+
 3.0.2 (2024-03-13)
 ------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/PKG-INFO new/unyt-3.0.3/PKG-INFO
--- old/unyt-3.0.2/PKG-INFO     2024-03-13 07:33:56.847813000 +0100
+++ new/unyt-3.0.3/PKG-INFO     2024-07-02 15:39:56.505619300 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: unyt
-Version: 3.0.2
+Version: 3.0.3
 Summary: A package for handling numpy arrays with units
 Author-email: The yt project <yt-...@python.org>
 License: BSD-3-Clause
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/docs/extensions/show_all_units.py 
new/unyt-3.0.3/docs/extensions/show_all_units.py
--- old/unyt-3.0.2/docs/extensions/show_all_units.py    2024-01-27 
13:22:26.000000000 +0100
+++ new/unyt-3.0.3/docs/extensions/show_all_units.py    2024-06-26 
16:21:25.000000000 +0200
@@ -175,22 +175,14 @@
     start_of_line = start_of_line.translate(to_separator)
     vertical_separator = vertical_separator.translate(to_separator)
     end_of_line = end_of_line.translate(to_separator)
-    separator = "{}{}{}".format(
-        start_of_line,
-        vertical_separator.join([x * line_marker for x in sizes]),
-        end_of_line,
-    )
+    separator = f"{start_of_line}{vertical_separator.join([x * line_marker for 
x in sizes])}{end_of_line}"
     # determine header separator
     th_separator_tr = maketrans("-", "=")
     start_of_line = start_of_line.translate(th_separator_tr)
     line_marker = line_marker.translate(th_separator_tr)
     vertical_separator = vertical_separator.translate(th_separator_tr)
     end_of_line = end_of_line.translate(th_separator_tr)
-    th_separator = "{}{}{}".format(
-        start_of_line,
-        vertical_separator.join([x * line_marker for x in sizes]),
-        end_of_line,
-    )
+    th_separator = f"{start_of_line}{vertical_separator.join([x * line_marker 
for x in sizes])}{end_of_line}"
     # prepare result
     table.append(separator)
     # set table header
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/docs/usage.rst 
new/unyt-3.0.3/docs/usage.rst
--- old/unyt-3.0.2/docs/usage.rst       2024-01-27 13:22:26.000000000 +0100
+++ new/unyt-3.0.3/docs/usage.rst       2024-07-01 19:41:17.000000000 +0200
@@ -1494,7 +1494,7 @@
 One important caveat is that using Dask array functions may strip units:
 
     >>> da.sum(x_da).compute()
-    49995000
+    np.int64(49995000)
 
 For simple reductions, you can use the :mod:`reduce_with_units` function:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/pyproject.toml 
new/unyt-3.0.3/pyproject.toml
--- old/unyt-3.0.2/pyproject.toml       2024-03-13 07:25:16.000000000 +0100
+++ new/unyt-3.0.3/pyproject.toml       2024-07-01 19:41:17.000000000 +0200
@@ -124,7 +124,6 @@
     "error",
     "ignore:Matplotlib is currently using agg, which is a non-GUI backend, so 
cannot show the figure.:UserWarning",
     "ignore:FigureCanvasAgg is non-interactive, and thus cannot be 
shown:UserWarning",
-    "ignore:In accordance with NEP 32:DeprecationWarning",
     "ignore:distutils Version classes are deprecated. Use packaging.version 
instead.:DeprecationWarning",
     'ignore:datetime\.datetime\.utcfromtimestamp\(\) is 
deprecated:DeprecationWarning', # https://github.com/dateutil/dateutil/pull/1285
     'ignore:mpnumeric is deprecated:DeprecationWarning', # sympy 1.12 VS 
mpmath 1.4, solution: https://github.com/sympy/sympy/pull/25290
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/tox.ini new/unyt-3.0.3/tox.ini
--- old/unyt-3.0.2/tox.ini      2024-01-27 13:22:26.000000000 +0100
+++ new/unyt-3.0.3/tox.ini      2024-07-01 19:41:17.000000000 +0200
@@ -20,8 +20,8 @@
 deps =
     pytest
     h5py
-    pint
-    astropy
+    !py39: pint
+    !py39: astropy!=6.1.1
     coverage[toml]>=5.0
     pytest-cov
     pytest-doctestplus
@@ -32,6 +32,14 @@
     pytest --cov=unyt --cov-append --doctest-modules --doctest-plus 
--doctest-rst --basetemp={envtmpdir}
     coverage report --omit='.tox/*'
 
+[testenv:py39]
+# skip doctest on py39 because doctests require numpy>=2.0 and all optional 
deps,
+# but some of our optional deps (pint, astropy) don't have a version that 
support
+# both numpy>=2.0 and Python 3.9
+commands=
+    pytest --cov=unyt --cov-append --basetemp={envtmpdir}
+    coverage report --omit='.tox/*'
+
 [testenv:py39-versions]
 deps =
     docutils
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt/_array_functions.py 
new/unyt-3.0.3/unyt/_array_functions.py
--- old/unyt-3.0.2/unyt/_array_functions.py     2024-02-25 09:14:12.000000000 
+0100
+++ new/unyt-3.0.3/unyt/_array_functions.py     2024-07-02 15:31:26.000000000 
+0200
@@ -272,57 +272,57 @@
 
 
 @implements(np.intersect1d)
-def intersect1d(arr1, arr2, /, assume_unique=False, return_indices=False):
-    _validate_units_consistency((arr1, arr2))
+def intersect1d(ar1, ar2, assume_unique=False, return_indices=False):
+    _validate_units_consistency((ar1, ar2))
     retv = np.intersect1d._implementation(
-        np.asarray(arr1),
-        np.asarray(arr2),
+        np.asarray(ar1),
+        np.asarray(ar2),
         assume_unique=assume_unique,
         return_indices=return_indices,
     )
     if return_indices:
         return retv
     else:
-        return retv * arr1.units
+        return retv * ar1.units
 
 
 @implements(np.union1d)
-def union1d(arr1, arr2, /):
-    _validate_units_consistency((arr1, arr2))
-    return np.union1d._implementation(np.asarray(arr1), np.asarray(arr2)) * 
arr1.units
+def union1d(ar1, ar2):
+    _validate_units_consistency((ar1, ar2))
+    return np.union1d._implementation(np.asarray(ar1), np.asarray(ar2)) * 
ar1.units
 
 
 @implements(np.linalg.norm)
-def norm(x, /, *args, **kwargs):
+def norm(x, *args, **kwargs):
     return np.linalg.norm._implementation(np.asarray(x), *args, **kwargs) * 
x.units
 
 
 @implements(np.vstack)
-def vstack(tup, /):
+def vstack(tup, **kwargs):
     ret_units = _validate_units_consistency(tup)
-    return np.vstack._implementation([np.asarray(_) for _ in tup]) * ret_units
+    return np.vstack._implementation([np.asarray(_) for _ in tup], **kwargs) * 
ret_units
 
 
 @implements(np.hstack)
-def hstack(tup, /):
+def hstack(tup, **kwargs):
     ret_units = _validate_units_consistency(tup)
-    return np.vstack._implementation([np.asarray(_) for _ in tup]) * ret_units
+    return np.vstack._implementation([np.asarray(_) for _ in tup], **kwargs) * 
ret_units
 
 
 @implements(np.dstack)
-def dstack(tup, /):
+def dstack(tup):
     ret_units = _validate_units_consistency(tup)
     return np.dstack._implementation([np.asarray(_) for _ in tup]) * ret_units
 
 
 @implements(np.column_stack)
-def column_stack(tup, /):
+def column_stack(tup):
     ret_units = _validate_units_consistency(tup)
     return np.column_stack._implementation([np.asarray(_) for _ in tup]) * 
ret_units
 
 
 @implements(np.stack)
-def stack(arrays, /, axis=0, out=None):
+def stack(arrays, axis=0, out=None, **kwargs):
     ret_units = _validate_units_consistency(arrays)
     if out is None:
         return (
@@ -330,7 +330,7 @@
             * ret_units
         )
     res = np.stack._implementation(
-        [np.asarray(_) for _ in arrays], axis=axis, out=np.asarray(out)
+        [np.asarray(_) for _ in arrays], axis=axis, out=np.asarray(out), 
**kwargs
     )
     if getattr(out, "units", None) is not None:
         out.units = ret_units
@@ -678,8 +678,8 @@
 
 
 @implements(np.ediff1d)
-def ediff1d(a, *args, **kwargs):
-    return diff_helper(np.ediff1d, a, *args, **kwargs)
+def ediff1d(ary, *args, **kwargs):
+    return diff_helper(np.ediff1d, ary, *args, **kwargs)
 
 
 @implements(np.ptp)
@@ -874,7 +874,8 @@
 
 
 @implements(np.einsum)
-def einsum(subscripts, *operands, out=None, **kwargs):
+def einsum(*operands, out=None, **kwargs):
+    subscripts, *operands = operands
     ret_units = _validate_units_consistency(operands)
 
     if out is not None:
@@ -962,7 +963,7 @@
         arr = np.asfarray._implementation(np.asarray(a), dtype=dtype)  # noqa: 
NPY201
         return arr * ret_units
 
-    _trapezoid_func = np.trapz
+    _trapezoid_func = np.trapz  # noqa: NPY201
 
 elif NUMPY_VERSION >= Version("2.0.0dev0"):
     # functions that were added in numpy 2.0.0
@@ -992,7 +993,7 @@
 
 if hasattr(np, "in1d"):
 
-    @implements(np.in1d)
+    @implements(np.in1d)  # noqa: NPY201
     def in1d(ar1, ar2, *args, **kwargs):
         _validate_units_consistency((ar1, ar2))
         return np.isin._implementation(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt/_parsing.py 
new/unyt-3.0.3/unyt/_parsing.py
--- old/unyt-3.0.2/unyt/_parsing.py     2024-02-24 15:11:41.000000000 +0100
+++ new/unyt-3.0.3/unyt/_parsing.py     2024-06-26 16:21:25.000000000 +0200
@@ -85,9 +85,6 @@
             unit_expr, global_dict=global_dict, 
transformations=unit_text_transform
         )
     except Exception as e:
-        msg = "Unit expression '{}' raised an error during 
parsing:\n{}".format(
-            unit_expr,
-            repr(e),
-        )
+        msg = f"Unit expression '{unit_expr}' raised an error during 
parsing:\n{e!r}"
         raise UnitParseError(msg)
     return unit_expr
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt/_version.py 
new/unyt-3.0.3/unyt/_version.py
--- old/unyt-3.0.2/unyt/_version.py     2024-03-13 07:33:56.000000000 +0100
+++ new/unyt-3.0.3/unyt/_version.py     2024-07-02 15:39:56.000000000 +0200
@@ -12,5 +12,5 @@
 __version_tuple__: VERSION_TUPLE
 version_tuple: VERSION_TUPLE
 
-__version__ = version = '3.0.2'
-__version_tuple__ = version_tuple = (3, 0, 2)
+__version__ = version = '3.0.3'
+__version_tuple__ = version_tuple = (3, 0, 3)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt/array.py new/unyt-3.0.3/unyt/array.py
--- old/unyt-3.0.2/unyt/array.py        2024-03-12 16:09:51.000000000 +0100
+++ new/unyt-3.0.3/unyt/array.py        2024-07-01 19:41:17.000000000 +0200
@@ -1255,7 +1255,7 @@
         >>> from unyt import km
         >>> data = [3, 8, 7]*km
         >>> print(np.argsort(data))
-        [0 2 1]
+        [0 2 1] km
         >>> print(data.argsort())
         [0 2 1]
         """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt/exceptions.py 
new/unyt-3.0.3/unyt/exceptions.py
--- old/unyt-3.0.2/unyt/exceptions.py   2024-01-27 13:22:26.000000000 +0100
+++ new/unyt-3.0.3/unyt/exceptions.py   2024-06-26 16:21:25.000000000 +0200
@@ -148,11 +148,10 @@
         super().__init__()
 
     def __str__(self):
-        err = (
-            "The %s unit system does not have a MKS current base unit"
-            % self.unit_system_name
+        return (
+            f"The {self.unit_system_name} unit system does not have "
+            "a MKS current base unit"
         )
-        return err
 
 
 class MKSCGSConversionError(UnytError):
@@ -343,5 +342,5 @@
     def __str__(self):
         return (
             "Cannot create unit system with inconsistent mapping from "
-            "dimensions to units. Received:\n%s" % self.units_map
+            f"dimensions to units. Received:\n{self.units_map}"
         )
Binary files old/unyt-3.0.2/unyt/tests/data/unyt_array_sympy1.8.pickle and 
new/unyt-3.0.3/unyt/tests/data/unyt_array_sympy1.8.pickle differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt/tests/test_array_functions.py 
new/unyt-3.0.3/unyt/tests/test_array_functions.py
--- old/unyt-3.0.2/unyt/tests/test_array_functions.py   2024-02-25 
09:14:12.000000000 +0100
+++ new/unyt-3.0.3/unyt/tests/test_array_functions.py   2024-07-02 
15:31:26.000000000 +0200
@@ -1,5 +1,7 @@
 # tests for NumPy __array_function__ support
+import inspect
 import re
+import warnings
 from importlib.metadata import version
 
 import numpy as np
@@ -24,6 +26,13 @@
 
 NUMPY_VERSION = Version(version("numpy"))
 
+
+VAR_POSITIONAL = inspect.Parameter.VAR_POSITIONAL
+VAR_KEYWORD = inspect.Parameter.VAR_KEYWORD
+POSITIONAL_ONLY = inspect.Parameter.POSITIONAL_ONLY
+KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY
+POSITIONAL_OR_KEYWORD = inspect.Parameter.POSITIONAL_OR_KEYWORD
+
 # this is a subset of NOT_HANDLED_FUNCTIONS for which there's nothing to do
 # because they don't apply to (real) numeric types
 # or they work as expected out of the box
@@ -154,7 +163,7 @@
 
 
 if NUMPY_VERSION >= Version("2.0.0dev0"):
-    # the followin all work out of the box (tested)
+    # the following all work out of the box (tested)
     NOOP_FUNCTIONS |= {
         np.linalg.cross,
         np.linalg.diagonal,
@@ -175,6 +184,11 @@
         np.vecdot,
     }
 
+if NUMPY_VERSION >= Version("2.1.0dev0"):
+    NOOP_FUNCTIONS |= {
+        np.unstack,
+    }
+
 # Functions for which behaviour is intentionally left to default
 IGNORED_FUNCTIONS = {
     np.i0,
@@ -184,35 +198,47 @@
     np.savez_compressed,
 }
 
-
+# map subsets of deprecated functions to the version they were removed
+# so that we can drop the ones that are not present in any version we support
 DEPRECATED_FUNCTIONS = {
-    "alen",  # deprecated in numpy 1.18, removed in 1.22
-    "asscalar",  # deprecated in numpy 1.18, removed in 1.22
-    "fv",  # deprecated in numpy 1.18, removed in 1.20
-    "ipmt",  # deprecated in numpy 1.18, removed in 1.20
-    "irr",  # deprecated in numpy 1.18, removed in 1.20
-    "mirr",  # deprecated in numpy 1.18, removed in 1.20
-    "nper",  # deprecated in numpy 1.18, removed in 1.20
-    "npv",  # deprecated in numpy 1.18, removed in 1.20
-    "pmt",  # deprecated in numpy 1.18, removed in 1.20
-    "ppmt",  # deprecated in numpy 1.18, removed in 1.20
-    "pv",  # deprecated in numpy 1.18, removed in 1.20
-    "rank",  # deprecated in numpy 1.10, removed in 1.18
-    "rate",  # deprecated in numpy 1.18, removed in 1.20
-    "msort",  # deprecated in numpy 1.24
-    # numpy 1.25 deprecations
-    "product",
-    "cumproduct",
-    "round_",  # removed in 2.0
-    "sometrue",
-    "alltrue",
+    Version("1.20"): {
+        "fv",
+        "ipmt",
+        "irr",
+        "mirr",
+        "nper",
+        "npv",
+        "pmt",
+        "ppmt",
+        "pv",
+        "rate",
+    },
+    Version("1.22"): {
+        "alen",
+        "asscalar",
+    },
+    Version("2.0.0b1"): {
+        "msort",
+        "product",
+        "cumproduct",
+        "round_",
+        "sometrue",
+        "alltrue",
+    },
+    # functions that are deprecated but not yet removed in any known version
+    # should be added here
+    Version("999.999.999"): set(),
 }
 
 NOT_HANDLED_FUNCTIONS = NOOP_FUNCTIONS | UNSUPPORTED_FUNCTIONS | 
IGNORED_FUNCTIONS
 
-for func in DEPRECATED_FUNCTIONS:
-    if hasattr(np, func):
-        NOT_HANDLED_FUNCTIONS.add(getattr(np, func))
+with warnings.catch_warnings():
+    warnings.simplefilter("ignore", DeprecationWarning)
+    for removal_version, functions in DEPRECATED_FUNCTIONS.items():
+        if NUMPY_VERSION >= removal_version:
+            continue
+        for func in functions:
+            NOT_HANDLED_FUNCTIONS.add(getattr(np, func))
 
 
 def get_decorators(func):
@@ -930,7 +956,7 @@
 if NUMPY_VERSION >= Version("2.0.0dev0"):
     _trapezoid_func = np.trapezoid
 else:
-    _trapezoid_func = np.trapz
+    _trapezoid_func = np.trapz  # noqa: NPY201
 
 
 def test_trapezoid_no_x():
@@ -1202,16 +1228,25 @@
 
 
 @pytest.mark.parametrize(
-    "func, args",
+    "func_name, args",
     [
-        (np.split, (3, 2)),
-        (np.dsplit, (3,)),
-        (np.hsplit, (2,)),
-        (np.vsplit, (1,)),
-        (np.array_split, (3,)),
+        ("split", (3, 2)),
+        ("dsplit", (3,)),
+        ("hsplit", (2,)),
+        ("vsplit", (1,)),
+        ("array_split", (3,)),
+        pytest.param(
+            "unstack",
+            (),
+            marks=pytest.mark.skipif(
+                NUMPY_VERSION < Version("2.1.0dev0"),
+                reason="np.unstack is new in NumPy 2.1",
+            ),
+        ),
     ],
 )
-def test_xsplit(func, args):
+def test_xsplit(func_name, args):
+    func = getattr(np, func_name)
     x = [
         [
             [
@@ -1404,7 +1439,7 @@
 
 def test_savetxt(tmp_path):
     a = [1, 2, 3] * cm
-    with pytest.raises(
+    with pytest.warns(
         UserWarning,
         match=re.escape(
             "numpy.savetxt does not preserve units, "
@@ -1685,14 +1720,14 @@
 def test_in1d_mixed_units():
     a = [1, 2, 3] * cm
     with pytest.raises(UnitInconsistencyError):
-        np.in1d([1, 2], a)
+        np.in1d([1, 2], a)  # noqa: NPY201
 
 
 @pytest.mark.filterwarnings("ignore:`in1d` is deprecated. Use `np.isin` 
instead.")
 def test_in1d():
     a = [1, 2, 3] * cm
     b = [1, 2] * cm
-    assert np.all(np.in1d(b, a))
+    assert np.all(np.in1d(b, a))  # noqa: NPY201
 
 
 def test_place_mixed_units():
@@ -1965,3 +2000,146 @@
     res = np.interp(_x * cm, _xp * cm, _fp * K)
     assert type(res) is unyt_array
     assert res.units == K
+
+
+@pytest.mark.parametrize(
+    "target, helper",
+    sorted(
+        HANDLED_FUNCTIONS.items(),
+        key=lambda items: items[0].__name__,
+    ),
+    ids=lambda func: func.__name__,
+)
+class TestFunctionHelpersSignatureCompatibility:
+    """
+    Check that a helper function's signature is *at least* as flexible
+    as the helped (target) function's. E.g., any argument that is allowed 
positionally,
+    or as keyword, by the target must be re-exposed *somehow* by the helper.
+    We explicitly allow helper's signature to be *more* flexible than the 
target signature
+    by allowing *args and **kwargs catch-all arguments, which we use to limit 
code
+    duplication, and also help with forward and backward compatibility.
+    See https://github.com/astropy/astropy/issues/15703
+    """
+
+    # this test class is adapted from astropy.units
+
+    @staticmethod
+    def have_catchall_argument(parameters, kind) -> bool:
+        return any(p.kind is kind for p in parameters.values())
+
+    @staticmethod
+    def get_param_group(parameters, kinds: list) -> list[str]:
+        return [name for name, p in parameters.items() if p.kind in kinds]
+
+    def test_all_arguments_reexposed(self, target, helper):
+        try:
+            sig_target = inspect.signature(target)
+        except ValueError:
+            pytest.skip("Non Python function cannot be inspected at runtime")
+
+        params_target = sig_target.parameters
+        sig_helper = inspect.signature(helper)
+        params_helper = sig_helper.parameters
+
+        have_args_helper = self.have_catchall_argument(params_helper, 
VAR_POSITIONAL)
+        have_kwargs_helper = self.have_catchall_argument(params_helper, 
VAR_KEYWORD)
+
+        args_helper = list(params_helper.items())
+
+        pos_helper = 0
+        for nt, pt in params_target.items():
+            kt = pt.kind
+            if kt in (POSITIONAL_ONLY, POSITIONAL_OR_KEYWORD):
+                assert pos_helper < len(args_helper), (
+                    "helper's signature is too short; "
+                    "some arguments are not properly re-exposed"
+                )
+                nh, ph = args_helper[pos_helper]
+                if (kh := ph.kind) is not VAR_POSITIONAL:
+                    assert nh == nt, f"argument {nt!r} isn't re-exposed as 
positional"
+                    assert kh is kt, (
+                        f"helper is not re-exposing argument {nt!r} properly:"
+                        f"expected {kt}, got {kh}"
+                    )
+                    pos_helper += 1
+                    continue
+
+            if kt in (KEYWORD_ONLY, POSITIONAL_OR_KEYWORD):
+                if nt in params_helper:
+                    kh = params_helper[nt].kind
+                    assert kh is kt, (
+                        f"helper is not re-exposing argument {nt!r} properly: "
+                        f"expected {kt}, got {kh}"
+                    )
+                elif kt is KEYWORD_ONLY:
+                    assert (
+                        have_kwargs_helper
+                    ), f"argument {nt!r} is not re-exposed as keyword"
+                elif kt is POSITIONAL_OR_KEYWORD:
+                    assert (
+                        have_args_helper and have_kwargs_helper
+                    ), f"argument {nt!r} is not re-exposed as 
positional-or-keyword"
+            elif kt is VAR_POSITIONAL:
+                assert have_args_helper, "helper is missing a catch-all *args 
argument"
+            elif kt is VAR_KEYWORD:
+                assert (
+                    have_kwargs_helper
+                ), "helper is missing a catch-all **kwargs argument"
+
+    def test_known_arguments(self, target, helper):
+        # validate that all exposed arguments map to something in the target
+        try:
+            sig_target = inspect.signature(target)
+        except ValueError:
+            pytest.skip("Non Python function cannot be inspected at runtime")
+
+        params_target = sig_target.parameters
+        sig_helper = inspect.signature(helper)
+        params_helper = sig_helper.parameters
+
+        for kind in (POSITIONAL_ONLY, POSITIONAL_OR_KEYWORD):
+            args_target = self.get_param_group(params_helper, [kind])
+            args_helper = self.get_param_group(params_helper, [kind])
+
+            if (nhelper := len(args_helper)) > (ntarget := len(args_target)):
+                unknown: list[str] = args_helper[ntarget:]
+                raise AssertionError(
+                    f"Found unknown {kind} parameter(s) "
+                    "in helper's signature: "
+                    f"{unknown}, at position(s) {list(range(ntarget, 
nhelper))}"
+                )
+
+        # keyword-allowed
+        keyword_allowed_target = set(
+            self.get_param_group(params_target, [KEYWORD_ONLY, 
POSITIONAL_OR_KEYWORD])
+        )
+        keyword_allowed_helper = set(
+            self.get_param_group(params_helper, [KEYWORD_ONLY, 
POSITIONAL_OR_KEYWORD])
+        )
+
+        # additional private keyword-only argument are allowed because
+        # they are only intended for testing purposes.
+        # For instance, quantile has such a parameter '_q_unit'
+        keyword_allowed_helper = {
+            name for name in keyword_allowed_helper if not name.startswith("_")
+        }
+
+        diff = keyword_allowed_helper - keyword_allowed_target
+        assert not diff, (
+            "Found some keyword-allowed parameters in helper "
+            f"that are unknown to target: {diff}"
+        )
+
+        # finally, check that default values are correctly replicated
+        for name, ph in params_helper.items():
+            if name not in params_target:
+                # In a few cases, the helper defines names that are not in
+                # the target (e.g., a private name like _q_unit in quantile,
+                # or a *args, **kwargs that captures further arguments
+                # that do not matter. We let such cases slip by.
+                continue
+            pt = params_target[name]
+            assert ph.default == pt.default, (
+                f"Default value mismatch for argument {name!r}. "
+                f"Helper has {ph.default!r}, target has {pt.default!r}"
+            )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt/tests/test_unyt_array.py 
new/unyt-3.0.3/unyt/tests/test_unyt_array.py
--- old/unyt-3.0.2/unyt/tests/test_unyt_array.py        2024-03-12 
16:09:51.000000000 +0100
+++ new/unyt-3.0.3/unyt/tests/test_unyt_array.py        2024-07-01 
19:41:17.000000000 +0200
@@ -16,7 +16,6 @@
 import shutil
 import tempfile
 from importlib.metadata import version
-from pathlib import Path
 
 import numpy as np
 import pytest
@@ -851,30 +850,6 @@
 SYMPY_VERSION = Version(version("sympy"))
 
 
-@pytest.mark.xfail(
-    condition=(SYMPY_VERSION == Version("1.12")),
-    reason="regression in sympy 1.12",
-    raises=AssertionError,
-    strict=True,
-)
-@pytest.mark.xfail(
-    condition=(SYMPY_VERSION in (Version("1.9"), Version("1.10"))),
-    reason="Not resolved upstream as of sympy 1.10",
-    raises=AttributeError,
-    strict=True,
-)
-def test_unpickling_old_array():
-    # see https://github.com/sympy/sympy/issues/22241
-    # the expected error is "AttributeError: 'One' object has no attribute 
'__dict__'"
-    PFILE = Path(__file__).parent / "data" / "unyt_array_sympy1.8.pickle"
-    with open(PFILE, "rb") as fh:
-        arr = pickle.load(fh)
-
-    # this comparison fails with sympy==1.12
-    # see https://github.com/sympy/sympy/issues/25134
-    assert arr.units.dimensions == cm.dimensions
-
-
 def test_copy():
     quan = unyt_quantity(1, "g")
     arr = unyt_array([1, 2, 3], "cm")
@@ -1546,7 +1521,8 @@
 
     reg.add("code_length", 10.0, dimensions.length)
 
-    warr = unyt_array(np.random.random((256, 256)), "code_length", 
registry=reg)
+    rng = np.random.default_rng()
+    warr = unyt_array(rng.random((256, 256)), "code_length", registry=reg)
 
     warr.write_hdf5("test.h5")
 
@@ -1565,8 +1541,8 @@
 
     # test code to overwrite existing dataset with data that has a different
     # shape
-
-    warr = unyt_array(np.random.random((255, 255)), "code_length", 
registry=reg)
+    rng = np.random.default_rng()
+    warr = unyt_array(rng.random((255, 255)), "code_length", registry=reg)
 
     warr.write_hdf5("test.h5")
 
@@ -2165,9 +2141,10 @@
     curdir = os.getcwd()
     os.chdir(tmpdir)
 
-    a = unyt_array(np.random.random(10), "kpc")
-    b = unyt_array(np.random.random(10), "Msun")
-    c = unyt_array(np.random.random(10), "km/s")
+    rng = np.random.default_rng()
+    a = unyt_array(rng.random(10), "kpc")
+    b = unyt_array(rng.random(10), "Msun")
+    c = unyt_array(rng.random(10), "km/s")
 
     savetxt("arrays.dat", [a, b, c], delimiter=",")
 
@@ -2221,8 +2198,9 @@
 
 
 def test_trig_ufunc_degrees():
+    rng = np.random.default_rng()
     for ufunc in (np.sin, np.cos, np.tan):
-        degree_values = np.random.random(10) * degree
+        degree_values = rng.random(10) * degree
         radian_values = degree_values.in_units("radian")
         assert_array_equal(ufunc(degree_values), ufunc(radian_values))
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt/unit_object.py 
new/unyt-3.0.3/unyt/unit_object.py
--- old/unyt-3.0.2/unyt/unit_object.py  2024-02-24 15:11:41.000000000 +0100
+++ new/unyt-3.0.3/unyt/unit_object.py  2024-07-01 19:41:17.000000000 +0200
@@ -467,7 +467,7 @@
                 "Failed to cast it to a float."
             )
 
-        if self.dimensions is logarithmic and p != 1.0:
+        if self.dimensions is logarithmic and p != 1:
             raise InvalidUnitOperation(f"Tried to raise '{self}' to power 
'{p}'")
 
         return Unit(
@@ -988,9 +988,8 @@
         return (float(base_value), dimensions)
 
     raise UnitParseError(
-        "Cannot parse for unit data from '%s'. Please supply"
-        " an expression of only Unit, Symbol, Pow, and Mul"
-        "objects." % str(unit_expr)
+        f"Cannot parse for unit data from {str(unit_expr)!r}. Please supply "
+        "an expression of only Unit, Symbol, Pow, and Mul objects."
     )
 
 
@@ -1006,15 +1005,15 @@
     elif isinstance(dimensions, Pow):
         if not isinstance(dimensions.args[1], Number):
             raise UnitParseError(
-                "Dimensionality expression '%s' contains a "
-                "unit symbol as a power." % dimensions
+                f"Dimensionality expression '{dimensions}' contains a "
+                "unit symbol as a power."
             )
     elif isinstance(dimensions, (Add, Number)):
         if not isinstance(dimensions, One):
             raise UnitParseError(
                 "Only dimensions that are instances of Pow, "
                 "Mul, or symbols in the base dimensions are "
-                "allowed.  Got dimensions '%s'" % dimensions
+                f"allowed.  Got dimensions '{dimensions}'"
             )
     elif not isinstance(dimensions, Basic):
         raise UnitParseError(f"Bad dimensionality expression '{dimensions}'.")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt/unit_registry.py 
new/unyt-3.0.3/unyt/unit_registry.py
--- old/unyt-3.0.2/unyt/unit_registry.py        2024-02-24 15:11:41.000000000 
+0100
+++ new/unyt-3.0.3/unyt/unit_registry.py        2024-06-26 16:21:25.000000000 
+0200
@@ -179,8 +179,8 @@
 
         if symbol not in self.lut:
             raise SymbolNotFoundError(
-                "Tried to remove the symbol '%s', but it does not exist "
-                "in this registry." % symbol
+                r"Tried to remove the symbol {symbol!r}, but it does not exist 
"
+                "in this registry."
             )
 
         del self.lut[symbol]
@@ -205,8 +205,8 @@
 
         if symbol not in self.lut:
             raise SymbolNotFoundError(
-                "Tried to modify the symbol '%s', but it does not exist "
-                "in this registry." % symbol
+                f"Tried to modify the symbol {symbol!r}, but it does not exist 
"
+                "in this registry."
             )
 
         if hasattr(base_value, "in_base"):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt.egg-info/PKG-INFO 
new/unyt-3.0.3/unyt.egg-info/PKG-INFO
--- old/unyt-3.0.2/unyt.egg-info/PKG-INFO       2024-03-13 07:33:56.000000000 
+0100
+++ new/unyt-3.0.3/unyt.egg-info/PKG-INFO       2024-07-02 15:39:56.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: unyt
-Version: 3.0.2
+Version: 3.0.3
 Summary: A package for handling numpy arrays with units
 Author-email: The yt project <yt-...@python.org>
 License: BSD-3-Clause
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unyt-3.0.2/unyt.egg-info/SOURCES.txt 
new/unyt-3.0.3/unyt.egg-info/SOURCES.txt
--- old/unyt-3.0.2/unyt.egg-info/SOURCES.txt    2024-03-13 07:33:56.000000000 
+0100
+++ new/unyt-3.0.3/unyt.egg-info/SOURCES.txt    2024-07-02 15:39:56.000000000 
+0200
@@ -91,5 +91,4 @@
 unyt/tests/test_unyt_array.py
 unyt/tests/test_unyt_testing.py
 unyt/tests/data/__init__.py
-unyt/tests/data/old_json_registry.txt
-unyt/tests/data/unyt_array_sympy1.8.pickle
\ No newline at end of file
+unyt/tests/data/old_json_registry.txt
\ No newline at end of file

Reply via email to