Description
- a detailed description of the bug or problem you are having
When using pytest.approx with custom types which are implicitly convertible to numpy arrays, the following error is observed:
E AssertionError: assert <test_matrix_...x7f9169ac4ca0> == approx([1.0 ±....0 ± 4.0e-06])
E (pytest_assertion plugin: representation of details failed: ~/.venv/lib/python3.10/site-packages/_pytest/python_api.py:175: AttributeError: 'MyType' object has no attribute 'shape'.
E Probably an object has a faulty __repr__.)
Note: The line number in the error message is a little off from the current head. That line is here.
Looking at the code, pytest.approx
sensibly chooses the numpy implementation ApproxNumpy
, because the expected value is implicitly convertible to a numpy array. However, the shape check assumes that other_side
is a numpy array (rather than assuming its implicitly convertible to a numpy array, like the expected value is) and so assumes that it has a shape
attribute (which is not part of how approx determines if something is a numpy array).
It seems like either:
ApproxNumpy._repr_compare()
needs to convertother_side
to a numpy array (ie_as_numpy_array(other_side)
)_as_numpy_array
needs to check if the object has ashape
attribute, if the code is going to assume that's the case
-
output of
pip list
from the virtual environment you are using:
Relevant packages:
numpy: 1.26.1 -
pytest and operating system versions
pytest: 7.4.3
Ubuntu: 22.04
- minimal example if possible
import numpy as np
import pytest
class MyType:
"""Type which is implicitly convertible to a numpy array."""
def __init__(self, vals):
self.vals = vals
def __repr__(self):
return f"{self.__class__.__name__}({self.vals})"
def __array__(self, dtype=None, copy=None):
return np.array(self.vals)
def test_approx_eq():
vec1 = MyType([1.0, 2.0, 3.0])
vec2 = MyType([1.0, 2.0, 4.0])
assert vec1 == pytest.approx(vec2)