-
Notifications
You must be signed in to change notification settings - Fork 270
Faster check for isiterable #545
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Yeah, this is probably better. Thanks @groutr! |
|
@eriknw I think this should be reverted, the python documentation says:
The previous code did that. The new code will fail for objects that iterate using the |
|
I'm convinced. Thanks @LincolnPuzey! We should have been more careful. |
|
@LincolnPuzey thank for pointing that out. This lead me down a long rabbit hole of understanding the sequence protocol more deeply. Basically are three cases that can exist (AFAICT):
Here is an alternative implementation: def test_iterable(obj):
xiter = getattr(obj, '__iter__', no_default)
if xiter is None:
return False
elif xiter is no_default:
return hasattr(obj, '__getitem__')
elif callable(xiter):
return True
else:
return FalseAnd some test cases and benchmarks class T1:
# Case 2
def __getitem__(self, i):
return i
class T2:
# Case 1
def __iter__(self):
return self
def __next__(self):
return 0
class T3:
# Case 3
def __getitem__(self, i):
return i
__iter__ = None
class T4:
# Case 1, but with no __next__
def __iter__(self):
return iter([])
class T5:
# Case 1, but __iter__ not callable.
__iter__ = False
class T6:
# Case 3
__iter__ = NoneThere might still be some value in going with an alternative implementation of |
|
thanks for the deep dive @groutr I like your test cases. class T7:
def __iter__(self):
raise TypeErrorBut I think your alternate implementation would classify that as iterable. For now, I have opened a PR reverting the change back and adding some more test cases in #551. I will leave it up to @eriknw to consider the alternative implementation. |
|
Yeah, simple is good here. @groutr's exploration of the rabbit hole is pretty interesting though, and the |
Use hasattr to check if something is iterable or not by checking specifically for iter method. When the input is not an iterable, catching the exception is expensive.
ping: @eriknw