-
-
Notifications
You must be signed in to change notification settings - Fork 10.9k
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
base: main
Are you sure you want to change the base?
Conversation
f892a34
to
bdc631a
Compare
There was a problem hiding this 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
eb20ddc
to
ed71d6e
Compare
ed71d6e
to
4bcef07
Compare
…son fails.