Skip to content

Commit 015e1e8

Browse files
committed
Add and pass tests
1 parent 6c13843 commit 015e1e8

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

pandas/_libs/lib.pyx

+3-1
Original file line numberDiff line numberDiff line change
@@ -1049,8 +1049,10 @@ cdef inline bint c_is_list_like(object obj, bint allow_sets) except -1:
10491049
# we do not count strings/unicode/bytes as list-like
10501050
and not isinstance(obj, (str, bytes))
10511051
# exclude zero-dimensional numpy arrays, effectively scalars
1052-
# and not (hasattr(obj, "ndim") and obj.ndim == 0)
10531052
and not cnp.PyArray_IsZeroDim(obj)
1053+
# extra check for numpy-like objects which aren't captured by
1054+
# the above
1055+
and not (hasattr(obj, "ndim") and obj.ndim == 0)
10541056
# exclude sets if allow_sets is False
10551057
and not (allow_sets is False and isinstance(obj, abc.Set))
10561058
)

pandas/tests/dtypes/test_inference.py

+56
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,51 @@
5555
from pandas.core.arrays import IntegerArray
5656

5757

58+
class MockNumpyLikeArray:
59+
"""
60+
A class which is numpy-like (e.g. Pint's Quantity) but not actually numpy
61+
The key is that it is not actually a numpy array so
62+
``util.is_array(mock_numpy_like_array_instance)`` returns ``False``. Other
63+
important properties are that the class defines a :meth:`__iter__` method
64+
(so that ``isinstance(abc.Iterable)`` returns ``True``) and has a
65+
:meth:`ndim` property which can be used as a check for whether it is a
66+
scalar or not.
67+
"""
68+
69+
def __init__(self, values):
70+
self._values = values
71+
72+
def __iter__(self):
73+
iter_values = iter(self._values)
74+
75+
def it_outer():
76+
yield from iter_values
77+
78+
return it_outer()
79+
80+
def __len__(self):
81+
return len(self._values)
82+
83+
def __array__(self, t=None):
84+
return self._values
85+
86+
@property
87+
def ndim(self):
88+
return self._values.ndim
89+
90+
@property
91+
def dtype(self):
92+
return self._values.dtype
93+
94+
@property
95+
def size(self):
96+
return self._values.size
97+
98+
@property
99+
def shape(self):
100+
return self._values.shape
101+
102+
58103
@pytest.fixture(params=[True, False], ids=str)
59104
def coerce(request):
60105
return request.param
@@ -94,6 +139,15 @@ def coerce(request):
94139
(np.ndarray((2,) * 4), True, "ndarray-4d"),
95140
(np.array([[[[]]]]), True, "ndarray-4d-empty"),
96141
(np.array(2), False, "ndarray-0d"),
142+
(MockNumpyLikeArray(np.ndarray((2,) * 1)), True, "duck-ndarray-1d"),
143+
(MockNumpyLikeArray(np.array([])), True, "duck-ndarray-1d-empty"),
144+
(MockNumpyLikeArray(np.ndarray((2,) * 2)), True, "duck-ndarray-2d"),
145+
(MockNumpyLikeArray(np.array([[]])), True, "duck-ndarray-2d-empty"),
146+
(MockNumpyLikeArray(np.ndarray((2,) * 3)), True, "duck-ndarray-3d"),
147+
(MockNumpyLikeArray(np.array([[[]]])), True, "duck-ndarray-3d-empty"),
148+
(MockNumpyLikeArray(np.ndarray((2,) * 4)), True, "duck-ndarray-4d"),
149+
(MockNumpyLikeArray(np.array([[[[]]]])), True, "duck-ndarray-4d-empty"),
150+
(MockNumpyLikeArray(np.array(2)), False, "duck-ndarray-0d"),
97151
(1, False, "int"),
98152
(b"123", False, "bytes"),
99153
(b"", False, "bytes-empty"),
@@ -154,6 +208,8 @@ def test_is_array_like():
154208
assert inference.is_array_like(Series([1, 2]))
155209
assert inference.is_array_like(np.array(["a", "b"]))
156210
assert inference.is_array_like(Index(["2016-01-01"]))
211+
assert inference.is_array_like(np.array([2, 3]))
212+
assert inference.is_array_like(MockNumpyLikeArray(np.array([2, 3])))
157213

158214
class DtypeList(list):
159215
dtype = "special"

0 commit comments

Comments
 (0)