Skip to content

Commit 386c750

Browse files
authored
Merge pull request #551 from LincolnPuzey/revert-isiterable-change
Revert "Faster isiterable when x isn't iterable." and add test cases for isiterable
2 parents 1aa72df + 10e97e4 commit 386c750

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

toolz/itertoolz.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,11 @@ def isiterable(x):
283283
>>> isiterable(5)
284284
False
285285
"""
286-
return hasattr(x, "__iter__")
286+
try:
287+
iter(x)
288+
return True
289+
except TypeError:
290+
return False
287291

288292

289293
def isdistinct(seq):

toolz/tests/test_itertoolz.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,34 @@ def test_unique():
106106

107107

108108
def test_isiterable():
109+
# objects that have a __iter__() or __getitem__() method are iterable
110+
# https://docs.python.org/3/library/functions.html#iter
111+
class IterIterable:
112+
def __iter__(self):
113+
return iter(["a", "b", "c"])
114+
115+
class GetItemIterable:
116+
def __getitem__(self, item):
117+
return ["a", "b", "c"][item]
118+
119+
# "if a class sets __iter__() to None, the class is not iterable"
120+
# https://docs.python.org/3/reference/datamodel.html#special-method-names
121+
class NotIterable:
122+
__iter__ = None
123+
124+
class NotIterableEvenWithGetItem:
125+
__iter__ = None
126+
127+
def __getitem__(self, item):
128+
return ["a", "b", "c"][item]
129+
109130
assert isiterable([1, 2, 3]) is True
110131
assert isiterable('abc') is True
132+
assert isiterable(IterIterable()) is True
133+
assert isiterable(GetItemIterable()) is True
111134
assert isiterable(5) is False
135+
assert isiterable(NotIterable()) is False
136+
assert isiterable(NotIterableEvenWithGetItem()) is False
112137

113138

114139
def test_isdistinct():

0 commit comments

Comments
 (0)