#18963 closed Cleanup/optimization (fixed)
Pattern for object model compatibility isn't friendly for subclasses
Reported by: | Aymeric Augustin | Owned by: | Aymeric Augustin |
---|---|---|---|
Component: | Python 3 | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
In the Python 3 documentation I recommended the following pattern for iterators:
class MyIterator(object): def __iter__(self): return self # implement some logic here def __next__(self): raise StopIteration # implement some logic here next = __next__ # Python 2 compatibility
A downside is that if a subclass overrides __next__
, it also has to repeat next = __next__
. This is tricky.
As of [20012b96] Django bundles six 1.2, which introduced six.Iterator to solve this problem.
This problem cannot cause regressions for people who have working code on Python 2, because they override next
, not __next__
. However I'd like to take advantage of six.Iterator
since it's technically more correct.
The same problem exists with __nonzero__ = __bool__
, __div__ = __truediv__
and __idiv__ = __truediv__
.
We could use a slightly more verbose pattern:
class Foo(object): def __nonzero__(self): return self.__bool__()
six.Iterator
uses type(self).__next__(self)
rather than self.__next__()
. I assume there's a good reason but I haven't figured it out. I'd like to understand it before making a decision.
Change History (3)
comment:1 by , 12 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Answer from #python-dev on the last question:
It's safer to mimick the interpreter's behavior closely, so let's adopt the same pattern.