diff --git a/pandas/_libs/testing.pyx b/pandas/_libs/testing.pyx index 679cde9932a7a..a8cfbd558aa50 100644 --- a/pandas/_libs/testing.pyx +++ b/pandas/_libs/testing.pyx @@ -21,7 +21,13 @@ from pandas.core.dtypes.missing import ( cdef bint isiterable(obj): - return hasattr(obj, '__iter__') + if hasattr(obj, '__iter__'): + try: + iter(obj) + return True + except (TypeError, IndexError) as e: + return False + return False cdef bint has_length(obj): diff --git a/pandas/tests/dtypes/test_inference.py b/pandas/tests/dtypes/test_inference.py index 46bc6d82b55db..cc492eacdd550 100644 --- a/pandas/tests/dtypes/test_inference.py +++ b/pandas/tests/dtypes/test_inference.py @@ -126,6 +126,9 @@ def size(self): def shape(self): return self._values.shape + def __getitem__(self, item): + return self._values[item] + # collect all objects to be tested for list-like-ness; use tuples of objects, # whether they are list-like or not (special casing for sets), and their ID diff --git a/pandas/tests/util/test_assert_almost_equal.py b/pandas/tests/util/test_assert_almost_equal.py index ab53707771be6..3384820631f48 100644 --- a/pandas/tests/util/test_assert_almost_equal.py +++ b/pandas/tests/util/test_assert_almost_equal.py @@ -8,6 +8,7 @@ Timestamp, ) import pandas._testing as tm +from pandas.tests.dtypes.test_inference import MockNumpyLikeArray def _assert_almost_equal_both(a, b, **kwargs): @@ -458,3 +459,16 @@ def test_assert_almost_equal_iterable_values_mismatch(): with pytest.raises(AssertionError, match=msg): tm.assert_almost_equal([1, 2], [1, 3]) + + +@pytest.mark.parametrize( + "obj", + [ + MockNumpyLikeArray(np.ndarray((2,) * 1)), + MockNumpyLikeArray(np.array([])), + MockNumpyLikeArray(np.array(2)), + ], + ids=["duck-ndarray-1d", "duck-ndarray-1d-empty", "duck-ndarray-0d"], +) +def test_assert_almost_equal_not_iterable(obj): + tm.assert_almost_equal(obj, obj)