[Python-ideas] discontinue iterable strings

eryk sun eryksun at gmail.com
Sun Aug 21 02:02:47 EDT 2016


On Sun, Aug 21, 2016 at 5:27 AM, Chris Angelico <rosuav at gmail.com> wrote:
> Hmm. It would somehow need to be recognized as "not iterable". I'm not
> sure how this detection is done; is it based on the presence/absence
> of __iter__, or is it by calling that method and seeing what comes
> back? If the latter, then sure, an __iter__ that raises would cover
> that.

PyObject_GetIter calls __iter__ (i.e. tp_iter) if it's defined. To get
a TypeError, __iter__ can return an object that's not an iterator,
i.e. an object that doesn't have a __next__ method (i.e. tp_iternext).
For example:

    >>> class C:
    ...     def __iter__(self): return self
    ...     def __getitem__(self, index): return 42
    ...
    >>> iter(C())
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: iter() returned non-iterator of type 'C'

If __iter__ isn't defined but __getitem__ is defined, then
PySeqIter_New is called to get a sequence iterator.

    >>> class D:
    ...     def __getitem__(self, index): return 42
    ...
    >>> it = iter(D())
    >>> type(it)
    <class 'iterator'>
    >>> next(it)
    42


More information about the Python-ideas mailing list