{"id":"0a68515ae8a245d8","repo":"pytest-dev/pytest","slug":"cannot-compare-actual-to-numpy-ndarray","errorCode":null,"errorMessage":"cannot compare '{actual}' to numpy.ndarray","messagePattern":"cannot compare '(.+?)' to numpy\\.ndarray","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/approx.py","lineNumber":227,"sourceCode":"        return _compare_approx(\n            self.expected,\n            message_data,\n            number_of_elements,\n            different_ids,\n            max_abs_diff,\n            max_rel_diff,\n        )\n\n    def __eq__(self, actual) -> bool:\n        import numpy as np\n\n        # self.expected is supposed to always be an array here.\n\n        if not np.isscalar(actual):\n            try:\n                actual = np.asarray(actual)\n            except Exception as e:\n                raise TypeError(f\"cannot compare '{actual}' to numpy.ndarray\") from e\n\n        if not np.isscalar(actual) and actual.shape != self.expected.shape:\n            return False\n\n        return super().__eq__(actual)\n\n    def _yield_comparisons(self, actual):\n        import numpy as np\n\n        # `actual` can either be a numpy array or a scalar, it is treated in\n        # `__eq__` before being passed to `ApproxBase.__eq__`, which is the\n        # only method that calls this one.\n\n        if np.isscalar(actual):\n            for i in np.ndindex(self.expected.shape):\n                yield actual, self.expected[i].item()\n        else:\n            for i in np.ndindex(self.expected.shape):","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/approx.py#L209-L245","documentation":"When comparing an actual value against approx(numpy_array), pytest's ApproxNumpy.__eq__ tries to convert the actual value to a numpy array via np.asarray(actual). If that conversion fails (e.g., the actual value is a string or an incompatible object), pytest raises TypeError because no meaningful element-wise comparison can be made.","triggerScenarios":"Comparing a non-array-compatible value to a numpy array approx: assert 'hello' == approx(np.array([1,2,3])). np.asarray('hello') raises, and the error is wrapped.","commonSituations":"A function under test returns a different type than expected (string instead of array), or a mock returns a sentinel value that is then compared against an approx array.","solutions":["Ensure the actual value is a numpy array, list, or scalar before comparing against approx(np.array(...)).","Add a type assertion before the comparison: assert isinstance(actual, np.ndarray).","Fix the code under test to return the expected array type."],"exampleFix":"# before\nassert get_name() == approx(np.array([1, 2, 3]))\n\n# after\nassert get_values() == approx(np.array([1, 2, 3]))","handlingStrategy":"type-guard","validationCode":"import numpy as np\n\ndef can_compare_as_ndarray(actual) -> bool:\n    \"\"\"Check if actual can be converted to a numpy array for approx comparison.\"\"\"\n    if np.isscalar(actual):\n        return True\n    try:\n        np.asarray(actual)\n        return True\n    except Exception:\n        return False\n\n# usage:\n# assert can_compare_as_ndarray(result), f'Cannot compare {type(result)} against numpy array'\n# assert result == approx(expected_array)","typeGuard":"import numpy as np\n\ndef is_ndarray_compatible(value) -> bool:\n    if np.isscalar(value):\n        return True\n    try:\n        arr = np.asarray(value)\n        return arr is not None\n    except Exception:\n        return False","tryCatchPattern":null,"preventionTips":["Ensure the function under test returns a numpy array, list, or scalar before comparing against approx(np.array).","Add a type check or assert before the approx comparison to catch unexpected return types early.","Use mocks that return realistic array values, not sentinel strings."],"tags":["approx","numpy","type-error","comparison"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}