PyCQA / modernize

Modernizes Python code for eventual Python 3 migration. Built on top of fissix (a fork of lib2to3)
https://modernize.readthedocs.org/
Other
355 stars 51 forks source link

Need fix for next vs __next__ iterator #136

Open bhawkins opened 8 years ago

bhawkins commented 8 years ago

Classes that implement an iterator have to provide a next method in Python 2 but a __next__ method in Python 3. See

https://www.python.org/dev/peps/pep-3114/

The six package includes the class six.Iterator which you can subclass and provide only a __next__ method.

daira commented 8 years ago

Is the desired fix to add six.Iterator to the end of the base class list of any class that statically defines a next method?

bhawkins commented 8 years ago

I think it'd be something like that, in addition to renaming the next method to __next__. I've attached a simple example. Output is below:

test.zip

$ python-modernize test_py2.py
RefactoringTool: Skipping implicit fixer: idioms
RefactoringTool: Skipping implicit fixer: set_literal
RefactoringTool: Skipping implicit fixer: ws_comma
RefactoringTool: No changes to test_py2.py
RefactoringTool: Files that need to be modified:
RefactoringTool: test_py2.py
$ python3 test_py2.py
Traceback (most recent call last):
  File "test_py2.py", line 19, in <module>
    for i in Foo(10):
TypeError: iter() returned non-iterator of type 'Foo'

I'm not sure you can always just add six.Iterator to the inheritance list. At least one special case is when the class inherits from object, e.g., Foo(object,Iterator) results in the exception

TypeError: duplicate base class object