Skip to content

ENH: Allow the user to specify the displayed precision when a comparison fails. #29135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

RECHE23
Copy link

@RECHE23 RECHE23 commented Jun 6, 2025

…son fails.

@RECHE23 RECHE23 force-pushed the precision_np_testing_compare_arrays branch from f892a34 to bdc631a Compare June 6, 2025 15:24
Copy link
Contributor

@tylerjereddy tylerjereddy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it might be useful to add a comment to the PR showcasing one or two scenarios where the new functionality would really shine in practice.

Without immediately commenting on how desirable the feature would be, while poking around locally to try to fix the test failure it seemed to me like if you want to do this you may also need to adjust assert_almost_equal() (which I almost never use, but still).

The other thing I had to do to make that failing test pass, after the above change, was to set precision at least as high as the value of decimal - 1, which maybe makes me a little nervous about complexity in the changed behavior, but maybe it isn't a huge deal.

hacky diff to fix failing test locally
diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py
index b108db5b98..7738a94c21 100644
--- a/numpy/testing/_private/utils.py
+++ b/numpy/testing/_private/utils.py
@@ -500,7 +500,8 @@ def print_assert_equal(test_string, actual, desired):
         raise AssertionError(msg.getvalue())
 
 
-def assert_almost_equal(actual, desired, decimal=7, err_msg='', verbose=True):
+def assert_almost_equal(actual, desired, decimal=7, err_msg='', verbose=True,
+                        *, precision=6):
     """
     Raises an AssertionError if two items are not equal up to desired
     precision.
@@ -600,14 +601,14 @@ def _build_err_msg():
             desiredr = desired
             desiredi = 0
         try:
-            assert_almost_equal(actualr, desiredr, decimal=decimal)
-            assert_almost_equal(actuali, desiredi, decimal=decimal)
+            assert_almost_equal(actualr, desiredr, decimal=decimal, precision=precision)
+            assert_almost_equal(actuali, desiredi, decimal=decimal, precision=precision)
         except AssertionError:
             raise AssertionError(_build_err_msg())
 
     if isinstance(actual, (ndarray, tuple, list)) \
             or isinstance(desired, (ndarray, tuple, list)):
-        return assert_array_almost_equal(actual, desired, decimal, err_msg)
+        return assert_array_almost_equal(actual, desired, decimal, err_msg, precision=precision)
     try:
         # If one of desired/actual is not finite, handle it specially here:
         # check that both are nan if any is a nan, and test for equality
diff --git a/numpy/testing/tests/test_utils.py b/numpy/testing/tests/test_utils.py
index fcf20091ca..3a44089d84 100644
--- a/numpy/testing/tests/test_utils.py
+++ b/numpy/testing/tests/test_utils.py
@@ -702,7 +702,7 @@ def test_error_message(self):
                         ' DESIRED: array([1.00000000002, 2.00000000003, '
                         '3.00004      ])')
         with pytest.raises(AssertionError, match=re.escape(expected_msg)):
-            self._assert_func(x, y, decimal=12)
+            self._assert_func(x, y, decimal=12, precision=11)
 
         # With the default value of decimal digits, only the 3rd element
         # differs. Note that we only check for the formatting of the arrays

@@ -1633,6 +1648,10 @@ def assert_allclose(actual, desired, rtol=1e-7, atol=0, equal_nan=True,
The error message to be printed in case of failure.
verbose : bool, optional
If True, the conflicting values are appended to the error message.
precision : int or None, optional
Number of digits of precision for floating point output (default 6).
May be None if `floatmode` is not `fixed`, to print as many digits as
Copy link
Contributor

@tylerjereddy tylerjereddy Jun 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the context of floatmode clear here? It isn't a parameter of the function for example. I'm probably just not smart enough to get it--related to set_printoptions() in a broader context? Maybe could be a bit clearer.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @tylerjereddy! Thank you for your feedback!

I have applied your suggestions.

This is my first pull request here, so I'm sorry if I don't follow proper procedure.

The need to expose the precision attribute came when our unittest wrapper was hiding 1e-15 differences behind a 6-digit formatter. For example:

>>> np.testing.assert_allclose([1., 2.], [1., 1.99999999999999], rtol=1e-15, atol=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/users/rchenard/.local/lib/python3.12/site-packages/numpy/testing/_private/utils.py", line 1504, in assert_allclose
    assert_array_compare(compare, actual, desired, err_msg=str(err_msg),
  File "/usr/lib64/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/users/rchenard/.local/lib/python3.12/site-packages/numpy/testing/_private/utils.py", line 797, in assert_array_compare
    raise AssertionError(msg)
AssertionError: 
Not equal to tolerance rtol=1e-15, atol=0

Mismatched elements: 1 / 2 (50%)
Max absolute difference: 9.99200722e-15
Max relative difference: 4.99600361e-15
 x: array([1., 2.])
 y: array([1., 2.])

It can become really hard to debug, since it's impossible to figure where the violation occurs.

@RECHE23 RECHE23 force-pushed the precision_np_testing_compare_arrays branch 2 times, most recently from eb20ddc to ed71d6e Compare June 7, 2025 13:25
@RECHE23 RECHE23 force-pushed the precision_np_testing_compare_arrays branch from ed71d6e to 4bcef07 Compare June 7, 2025 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants