classification
Title: collections.Iterator __subclasshook__ does not check if next() is callable
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 2.7
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: bruth, rhettinger, terry.reedy
Priority: normal Keywords:

Created on 2013-03-31 02:31 by bruth, last changed 2013-03-31 19:47 by terry.reedy. This issue is now closed.

Messages (6)
msg185606 - (view) Author: Byron Ruth (bruth) Date: 2013-03-31 02:45
Consider:

```python
class A(object):
    def __init__(self):
        self.r = iter(range(5))
    def __iter__(self):
        return self
    @property
    def next(self):
        return next(self.r)
```

The `next` method is a property, however:

```python
from collections import Iterator
a = A()
isinstance(a, Iterator) # True
next(a) # TypeError: 'int' object is not callable
```
msg185607 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2013-03-31 03:28
Sorry, this isn't bug.  The design of ABCs are to check for the existence to required named; none of them verify the signature.
msg185611 - (view) Author: Byron Ruth (bruth) Date: 2013-03-31 03:58
Understood. I am not sure it is appropriate to follow-up with a question here, but would this be a downstream issue? My understanding of the iterator protocol is that is assumes the __iter__ and next methods are implements. In the example, the next method is defined as a property, but is still identified as an iterator. This seems an incorrect _behavior_ somewhere, although I may have assumed the incorrect place.
msg185645 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2013-03-31 19:39
It's the nature of duck typing in a dynamic language.  You can tell whether something is present but can't tell whether it words correctly until you call it.

For example, in Python 3, all objects have __lt__ defined, but all it does is return NotImplemented.  So, you can't really tell whether something is orderable until you make the less-than call.

In your case, the rule is that if "next" is present, we assume that it is iterable, but it won't be until it is called that we can tell whether it is implemented correctly (i.e. is callable with zero arguments, returns a value, and raises StopIteration when done).
msg185649 - (view) Author: Byron Ruth (bruth) Date: 2013-03-31 19:42
Thank you for the education. I didn't think about duck-typing extending to the level of whether or not something is callable.. then again the property _could_ return a callable and it would be transparent to the caller.
msg185654 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2013-03-31 19:47
I responded to this on python-list.
History
Date User Action Args
2013-03-31 19:47:30terry.reedysetnosy: + terry.reedy
messages: + msg185654
2013-03-31 19:42:26bruthsetmessages: + msg185649
2013-03-31 19:39:14rhettingersetmessages: + msg185645
2013-03-31 03:58:57bruthsetmessages: + msg185611
2013-03-31 03:43:05ezio.melottisetstage: resolved
2013-03-31 03:28:37rhettingersetstatus: open -> closed

nosy: + rhettinger
messages: + msg185607

resolution: wont fix
2013-03-31 02:45:45bruthsetmessages: + msg185606
2013-03-31 02:31:06bruthcreate