On Sun, Aug 21, 2016 at 6:53 AM, Michael Selik <[email protected]> wrote:
> For that to make sense, Iterable should be a parent of C, or C should be a
> subclass of something registered as an Iterable. Otherwise it'd be creating
> a general recommendation to say ``__iter__ = None`` on every non-Iterable
> class, which would be silly.
Iterable is a one-trick pony ABC that formerly just checked for an
__iter__ method using any("__iter__" in B.__dict__ for B in
C.__mro__). It was mentioned that the default __getitem__ iterator can
be avoided by defining __iter__ as a callable that either directly or
indirectly raises a TypeError, but that's an instance of Iterable,
which is misleading.
In 3.6 you can instead set `__iter__ = None`. At the low-level,
slot_tp_iter has been updated to look for this with the following
code:
func = lookup_method(self, &PyId___iter__);
if (func == Py_None) {
Py_DECREF(func);
PyErr_Format(PyExc_TypeError,
"'%.200s' object is not iterable",
Py_TYPE(self)->tp_name);
return NULL;
}
At the high level, Iterable.__subclasshook__ calls _check_methods(C,
"__iter__"):
def _check_methods(C, *methods):
mro = C.__mro__
for method in methods:
for B in mro:
if method in B.__dict__:
if B.__dict__[method] is None:
return NotImplemented
break
else:
return NotImplemented
return True
_______________________________________________
Python-ideas mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/