Code

Opened 22 months ago

Closed 21 months ago

Last modified 21 months ago

#18963 closed Cleanup/optimization (fixed)

Pattern for object model compatibility isn't friendly for subclasses

Reported by: aaugustin Owned by: aaugustin
Component: Python 3 Version: master
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.

Attachments (0)

Change History (3)

comment:1 Changed 22 months ago by aaugustin

  • Owner changed from nobody to aaugustin
  • Status changed from new to assigned
  • Triage Stage changed from Unreviewed to Accepted

Answer from #python-dev on the last question:

That's the way the interpreter looks up __magic__ methods. They aren't looked up on the object but on the class of the object.

It's safer to mimick the interpreter's behavior closely, so let's adopt the same pattern.

comment:2 Changed 21 months ago by Aymeric Augustin <aymeric.augustin@…>

  • Resolution set to fixed
  • Status changed from assigned to closed

In fc10418fba4fb906e4265650b62c510d526d63f7:

Fixed #18963 -- Used a subclass-friendly pattern

for Python 2 object model compatibility methods.

comment:3 Changed 21 months ago by Aymeric Augustin <aymeric.augustin@…>

In d7688a010a34033a5cc8eecf7b1460169c0e056e:

[1.5.x] Fixed #18963 -- Used a subclass-friendly pattern

for Python 2 object model compatibility methods.

Backport of fc10418 from master.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.