8000 np.testing.assert_almost_equal Issue in Python 3.5 for numpy==1.15.0 · Issue #11743 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

np.testing.assert_almost_equal Issue in Python 3.5 for numpy==1.15.0 #11743

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

Closed
foohyfooh opened this issue Aug 15, 2018 · 17 comments
Closed

np.testing.assert_almost_equal Issue in Python 3.5 for numpy==1.15.0 #11743

foohyfooh opened this issue Aug 15, 2018 · 17 comments

Comments

@foohyfooh
Copy link

The issues seems to be that in numpy/testing/_private/utils.py (x_id == y_id).all() on Line 707 is returning a bool in Python 3.5 and thus calling all on it is giving an AttributeError.
This is causing errors when testing the Pyrr package.

Note: This issue occurs with numpy==1.15.0 but not numpy==1.14.5

Reproducing code example:

This is one of the four code snippets that has the error is occurring.

from __future__ import absolute_import, division, print_function
try:
    import unittest2 as unittest
except:
    import unittest
import numpy as np
from pyrr import Quaternion, Matrix44, Matrix33, Vector3, Vector4, euler

class test_matrix_quaternion(unittest.TestCase):
    def test_m44_q_equivalence(self):
        """Test for equivalance of matrix and quaternion rotations.

        Create a matrix and quaternion, rotate each by the same values
        then convert matrix<->quaternion and check the results are the same.
        """
        m = Matrix44.from_x_rotation(np.pi / 2.)
        mq = Quaternion.from_matrix(m)

        q = Quaternion.from_x_rotation(np.pi / 2.)
        qm = Matrix44.from_quaternion(q)

        self.assertTrue(np.allclose(np.dot([1., 0., 0., 1.], m), [1., 0., 0., 1.]))
        self.assertTrue(np.allclose(np.dot([1., 0., 0., 1.], qm), [1., 0., 0., 1.]))

        self.assertTrue(np.allclose(q * Vector4([1., 0., 0., 1.]), [1., 0., 0., 1.]))
        self.assertTrue(np.allclose(mq * Vector4([1., 0., 0., 1.]), [1., 0., 0., 1.]))

        np.testing.assert_almost_equal(q, mq, decimal=5)
        np.testing.assert_almost_equal(m, qm, decimal=5)

Error message:

The errors can be found at https://travis-ci.org/adamlwgriffiths/Pyrr/jobs/415907003
Lines: 486, 502, 518, 534

The following is the Traceback from Travis CI

======================================================================
ERROR: Test for equivalance of matrix and quaternion rotations.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/adamlwgriffiths/Pyrr/pyrr/tests/objects/test_equivalence.py", line 29, in test_m44_q_equivalence
    np.testing.assert_almost_equal(q, mq, decimal=5)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 568, in assert_almost_equal
    return assert_array_almost_equal(actual, desired, decimal, err_msg)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 964, in assert_array_almost_equal
    precision=decimal)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 736, in assert_array_compare
    flagged = func_assert_same_pos(x, y, func=isnan, hasval='nan')
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 707, in func_assert_same_pos
    if (x_id == y_id).all() != True:
AttributeError: 'bool' object has no attribute 'all'
======================================================================
ERROR: test_decompose (pyrr.tests.objects.test_matrix44.test_object_matrix44)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/adamlwgriffiths/Pyrr/pyrr/tests/objects/test_matrix44.py", line 326, in test_decompose
    np.testing.assert_almost_equal(m, expected_model)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 568, in assert_almost_equal
    return assert_array_almost_equal(actual, desired, decimal, err_msg)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 964, in assert_array_almost_equal
    precision=decimal)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 736, in assert_array_compare
    flagged = func_assert_same_pos(x, y, func=isnan, hasval='nan')
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 707, in func_assert_same_pos
    if (x_id == y_id).all() != True:
AttributeError: 'bool' object has no attribute 'all'
======================================================================
ERROR: test_normalize (pyrr.tests.objects.test_vector3.test_object_vector3)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/adamlwgriffiths/Pyrr/pyrr/tests/objects/test_vector3.py", line 77, in test_normalize
    np.testing.assert_almost_equal(v.normalized, [0.57735, 0.57735, 0.57735], decimal=5)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 568, in assert_almost_equal
    return assert_array_almost_equal(actual, desired, decimal, err_msg)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 964, in assert_array_almost_equal
    precision=decimal)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 736, in assert_array_compare
    flagged = func_assert_same_pos(x, y, func=isnan, hasval='nan')
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 707, in func_assert_same_pos
    if (x_id == y_id).all() != True:
AttributeError: 'bool' object has no attribute 'all'
======================================================================
ERROR: test_normalize (pyrr.tests.objects.test_vector4.test_object_vector4)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/adamlwgriffiths/Pyrr/pyrr/tests/objects/test_vector4.py", line 60, in test_normalize
    np.testing.assert_almost_equal(v.normalized, [0.5, 0.5, 0.5, 0.5], decimal=5)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 568, in assert_almost_equal
    return assert_array_almost_equal(actual, desired, decimal, err_msg)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 964, in assert_array_almost_equal
    precision=decimal)
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 736, in assert_array_compare
    flagged = func_assert_same_pos(x, y, func=isnan, hasval='nan')
  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/site-packages/numpy/testing/_private/utils.py", line 707, in func_assert_same_pos
    if (x_id == y_id).all() != True:
AttributeError: 'bool' object has no attribute 'all'

Numpy/Python version information:

1.15.0 3.5.5 |Anaconda, Inc.| (default, Apr 7 2018, 04:52:34) [MSC v.1900 64 bit (AMD64)]

@charris
Copy link
Member
charris commented Aug 15, 2018

Problem came in with #11122. What happens if you replace if (x_id == y_id).all() != True: by if not np.all(x_id == y_id): ?

@mhvk Thoughts?

@mhvk
Copy link
Contributor
mhvk commented Aug 15, 2018

Weird. But your suggestion should work. (I'm on holidays so won't be able to check too much or make a PR; @foohyfooh - if you can, that would be great!)

@charris
Copy link
Member
charris commented Aug 15, 2018

@foohyfooh Can you come up with simpler code that triggers the problem?

8000

@foohyfooh
Copy link
Author
import numpy as np
from pyrr.objects import Vector3
np.testing.assert_almost_equal(Vector3(), Vector3())

@charris
Copy link
Member
charris commented Aug 15, 2018

@foohyfooh I'm looking for something without outside dependencies so it can be added to numpy as a test.

@foohyfooh
Copy link
Author

@charris Sorry I didn't recognize that is what you were looking for. I don't think I have a test other than what is happening in the Pyrr library.

@charris
Copy link
Member
charris commented Aug 15, 2018

What is special about Vector3? We can make a testing class if needed.

@foohyfooh
Copy link
Author

Nothing is special about it. It is just that the classes in Pyrr allow for positional element access just like numpy arrays.
It is just that the interaction between np.testing.assert_almost_equal and Pyrr classes is broken in Python 3.5 but works fine in Python 3.3, 3.4 and 3.6.

@foohyfooh foohyfooh changed the title numpy/testing/_private/utils.py Issue in Python 3.5 for numpy==1.15.0 np.testing.assert_almost_equal Issue in Python 3.5 for numpy==1.15.0 Aug 15, 2018
@charris
Copy link
Member
charris commented Aug 15, 2018

So this is a Python change, not a NumPy 1.15 thing? Now you have me wondering why it should work. Are the Vector3 classes instances of list or some other sequence type?

@foohyfooh
Copy link
Author

But the test worked fine with NumPy 1.14.5 when using Python 3.5.
Is there any change that was made between 1.14.5 and 1.15.0 that a specific effect in Python 3.5 only?

@ewmoore
Copy link
Contributor
ewmoore commented Aug 15, 2018 via email

@charris
Copy link
Member
charris commented Aug 16, 2018

It looks like Vector3 subclasses ndarray, but the == operator returns boolean.

n [1]: from pyrr.objects import Vector3

In [2]: Vector3() == Vector3()
Out[2]: True

In [3]: array(()) == array(())
Out[3]: array([], dtype=bool)

Note that comparing arrays returns an array, but I suspect you have overloaded that operator and Vector3 no longer behaves like an array. That, in combination with the changes in testing, where it checks that it is working with an array and wrongly assumes that Vector3 acts like one -- it is an instance of ndarray after all -- and calls a method that the comparison result should have.

So, we can work around that maybe, but the base class you are using maybe should not inherit from ndarray.

@foohyfooh
Copy link
Author

@ewmoore Thanks for pointing that out. I can't believe that I missed that.

@foohyfooh
Copy link
Author

Thank you for helping me sort out this issue. I will attempt to resolve the issue in Pyrr and verify that everything is working as it should.
Sorry for blaming NumPy.

@charris
Copy link
Member
charris commented Aug 16, 2018

If you are looking for other ways to do things, the mailing list is a good resource. There have been recent additions to numpy, __array_ufunc__ in particular, that might be useful.

@charris
Copy link
Member
charris commented Aug 16, 2018

I'm thinking we should still make the suggested change on our end, as the dos and don'ts of subclassing are probably not as clearly set out as might be desired. In particular, scalars vs 1-D array returns can be a problem with a lot of functions.

@mhvk
Copy link
Contributor
mhvk commented Aug 16, 2018

@foohyfooh - definitely don't worry about making a bug report if we break something, even if it turns out to be something that really one shouldn't have relied upon!

charris added a commit to charris/numpy that referenced this issue Aug 17, 2018
Use np.all instead of the *.all method to be a bit more robust against
bad subclasses of ndarray that may change the behavior of the method.

Closes numpy#11743.
charris added a commit to charris/numpy that referenced this issue Aug 17, 2018
Use np.all instead of the *.all method to be a bit more robust against
bad subclasses of ndarray that may change the behavior of the method.

Closes numpy#11743.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants
0