pytest-dev/pytest · error · TypeError
cannot compare ' ' to numpy.ndarray
Error message
cannot compare '{actual}' to numpy.ndarray What it means
When approx() wraps a numpy array, ApproxNumpy.__eq__ tries to convert the compared value to an ndarray via np.asarray(actual). If that conversion raises any exception (the actual value is not array-like), pytest re-raises it as this TypeError, chaining the original cause. This protects the comparison from silently returning False on genuinely incompatible operands.
Solutions
- Ensure the actual value is array-like (list, tuple, or numpy array) before comparing: `assert np.asarray(actual) == approx(np.array([...]))`.
- Convert both sides explicitly with np.asarray so the failure happens with a clearer traceback.
- If comparing a single scalar to an array, compare against approx(scalar) instead of approx(array).
Example fix
# before
assert {'a': 1} == approx(np.array([1.0, 2.0]))
# after
assert np.array([1.0, 2.0]) == approx(np.array([1.0, 2.0])) Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
def is_array_compatible(value) -> bool:
if np.isscalar(value):
return True
try:
np.asarray(value)
return True
except Exception:
return False
# usage
if is_array_compatible(actual):
assert actual == approx(np_array) Type guard
import numpy as np
def is_ndarray_or_scalar(v) -> bool:
return np.isscalar(v) or isinstance(v, np.ndarray) Try / catch
try:
assert actual == approx(np_array)
except TypeError as e:
if 'cannot compare' in str(e):
raise AssertionError(f'actual not array-like: {actual!r}') from e
raise Prevention
- Coerce actual with np.asarray before comparing to approx(array).
- Avoid comparing approx(array) to dicts, strings, or None.
- For scalar-vs-array, use approx(scalar) on the right side.
When it happens
Trigger: Calling approx(np.array([1.0,2.0])) == some_object where some_object is a dict, a string, an object without __array__, or a ragged/nested structure numpy cannot broadcast. Triggered at ApproxNumpy.__eq__ (src/_pytest/approx.py:218-227) only when the expected value was itself a numpy array (or array-like with numpy imported).
Common situations: Comparing an array approximation against a dict/None/string; mixing array and scalar-with-mixed-types; passing an object that implements __array__ but raises internally; using a mock or custom container as the actual value.
Related errors
- absolute tolerance can't be NaN.
- absolute tolerance can't be negative
- absolute tolerance for a scalar value must be an int, float…
- approx() is not supported in a boolean context. Did you…
- expected value must support abs(...) when relative…
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/0a68515ae8a245d8.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/approx.py:227
return _compare_approx(
self.expected,
message_data,
number_of_elements,
different_ids,
max_abs_diff,
max_rel_diff,
)
def __eq__(self, actual) -> bool:
import numpy as np
# self.expected is supposed to always be an array here.
if not np.isscalar(actual):
try:
actual = np.asarray(actual)
except Exception as e:
raise TypeError(f"cannot compare '{actual}' to numpy.ndarray") from e
if not np.isscalar(actual) and actual.shape != self.expected.shape:
return False
return super().__eq__(actual)
def _yield_comparisons(self, actual):
import numpy as np
# `actual` can either be a numpy array or a scalar, it is treated in
# `__eq__` before being passed to `ApproxBase.__eq__`, which is the
# only method that calls this one.
if np.isscalar(actual):
for i in np.ndindex(self.expected.shape):
yield actual, self.expected[i].item()
else:
for i in np.ndindex(self.expected.shape):View on GitHub (pinned to 0d6fbdeffa)