4

CPython's implementation of collections.abc.Iterable has this bizarre idiom:

while False:
    yield None

Seems like the second line will never be executed. So why not just use pass instead?

The full code for the Iterable class is as follows:

class Iterable(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterable:
            return _check_methods(C, "__iter__")
        return NotImplemented

    __class_getitem__ = classmethod(GenericAlias)
Wood
  • 271
  • 1
  • 8
  • The implementation [arrived in this commit](https://github.com/python/cpython/commit/cd16bf640405065e4702539632ce577536207d88#diff-163c1525f292b112e15d4d78952fb8bc6a4b80e6ec8d608eea37edad2cfed28e), fully-formed. – Joe Oct 07 '22 at 03:46

1 Answers1

3

This idiom's use of yield means it will return an empty generator, as opposed to None:

>>> def iter():
...   if False:
...     yield None
... 
>>> iter()
<generator object iter at 0x7fd2cc134660>
>>> [i for i in iter()]
[]

If pass were used:

>>> def iter2():
...   pass
... 
>>> iter2()
>>> [i for i in iter2()]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not iterable

That TypeError is what is being avoided.

Joe
  • 29,416
  • 12
  • 68
  • 88