Skip to content

Commit e12549c

Browse files
authored
Merge pull request #466 from viourr/master
Add fixer for itertools
2 parents 7145e78 + 6a4064b commit e12549c

File tree

5 files changed

+137
-0
lines changed

5 files changed

+137
-0
lines changed

docs/futurize.rst

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ The complete set of fixers applied by ``futurize --stage1`` is:
103103
lib2to3.fixes.fix_ws_comma
104104
lib2to3.fixes.fix_xreadlines
105105
libfuturize.fixes.fix_absolute_import
106+
libfuturize.fixes.fix_itertools
106107
libfuturize.fixes.fix_next_call
107108
libfuturize.fixes.fix_print_with_import
108109
libfuturize.fixes.fix_raise

src/future/builtins/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
import builtins
1919
bytes = builtins.bytes
2020
dict = builtins.dict
21+
filter = builtins.filter
2122
int = builtins.int
2223
list = builtins.list
24+
map = builtins.map
2325
object = builtins.object
2426
range = builtins.range
2527
str = builtins.str
28+
zip = builtins.zip
2629
__all__ = []
2730
else:
2831
from future.types import (newbytes as bytes,
@@ -32,6 +35,9 @@
3235
newobject as object,
3336
newrange as range,
3437
newstr as str)
38+
from itertools import (ifilter as filter,
39+
imap as map,
40+
izip as zip)
3541
from future import utils
3642

3743

src/libfuturize/fixes/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969

7070
libfuturize_fix_names_stage1 = set([
7171
'libfuturize.fixes.fix_absolute_import',
72+
'libfuturize.fixes.fix_itertools',
7273
'libfuturize.fixes.fix_next_call', # obj.next() -> next(obj). Unlike
7374
# lib2to3.fixes.fix_next, doesn't change
7475
# the ``next`` method to ``__next__``.
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""
2+
For the ``future`` package.
3+
4+
Fixer for itertools methods that no longer deviate from builtins.
5+
6+
This applies to imap, izip, and ifilter
7+
8+
Adds this import line:
9+
10+
from builtins import filter, map, zip
11+
12+
at the top.
13+
"""
14+
15+
from lib2to3 import fixer_base
16+
17+
from libfuturize.fixer_util import touch_import_top
18+
19+
filter_expression = "name='ifilter'"
20+
map_expression = "name='imap'"
21+
zip_expression = "name='izip'"
22+
23+
class FixFilter(fixer_base.BaseFix):
24+
25+
PATTERN = """
26+
power<
27+
({0}) trailer< '(' args=[any] ')' >
28+
rest=any* >
29+
""".format(filter_expression)
30+
31+
def transform(self, node, results):
32+
touch_import_top(u'builtins', 'filter', node)
33+
34+
class FixMap(fixer_base.BaseFix):
35+
36+
PATTERN = """
37+
power<
38+
({0}) trailer< '(' args=[any] ')' >
39+
rest=any* >
40+
""".format(map_expression)
41+
42+
def transform(self, node, results):
43+
touch_import_top(u'builtins', 'map', node)
44+
45+
class FixZip(fixer_base.BaseFix):
46+
47+
PATTERN = """
48+
power<
49+
({0}) trailer< '(' args=[any] ')' >
50+
rest=any* >
51+
""".format(zip_expression)
52+
53+
def transform(self, node, results):
54+
touch_import_top(u'builtins', 'zip', node)

tests/test_future/test_futurize.py

+75
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,81 @@ def test_xrange(self):
453453
"""
454454
self.convert_check(before, after, ignore_imports=False)
455455

456+
def test_filter(self):
457+
"""
458+
Tests correct handling of itertools.ifilter
459+
"""
460+
before = """
461+
import itertools
462+
itertools.ifilter(lambda x: x%2, [1, 2, 3, 4])
463+
"""
464+
after = """
465+
from builtins import filter
466+
import itertools
467+
filter(lambda x: x%2, [1, 2, 3, 4])
468+
"""
469+
self.convert_check(before, after, ignore_imports=False)
470+
before = """
471+
from itertools import ifilter
472+
ifilter(lambda x: x%2, [1, 2, 3, 4])
473+
"""
474+
after = """
475+
from builtins import filter
476+
477+
filter(lambda x: x%2, [1, 2, 3, 4])
478+
"""
479+
self.convert_check(before, after, ignore_imports=False)
480+
481+
def test_map(self):
482+
"""
483+
Tests correct handling of itertools.imap
484+
"""
485+
before = """
486+
import itertools
487+
itertools.imap(pow, (2,3,10), (5,2,3))
488+
"""
489+
after = """
490+
from builtins import map
491+
import itertools
492+
map(pow, (2,3,10), (5,2,3))
493+
"""
494+
self.convert_check(before, after, ignore_imports=False)
495+
before = """
496+
from itertools import imap
497+
imap(pow, (2,3,10), (5,2,3))
498+
"""
499+
after = """
500+
from builtins import map
501+
502+
map(pow, (2,3,10), (5,2,3))
503+
"""
504+
self.convert_check(before, after, ignore_imports=False)
505+
506+
def test_zip(self):
507+
"""
508+
Tests correct handling of itertools.izip
509+
"""
510+
before = """
511+
import itertools
512+
itertools.izip('ABCD', 'xy')
513+
"""
514+
after = """
515+
from builtins import zip
516+
import itertools
517+
zip('ABCD', 'xy')
518+
"""
519+
self.convert_check(before, after, ignore_imports=False)
520+
before = """
521+
from itertools import izip
522+
izip('ABCD', 'xy')
523+
"""
524+
after = """
525+
from builtins import zip
526+
527+
zip('ABCD', 'xy')
528+
"""
529+
self.convert_check(before, after, ignore_imports=False)
530+
456531
def test_source_coding_utf8(self):
457532
"""
458533
Tests to ensure that the source coding line is not corrupted or

0 commit comments

Comments
 (0)