18
10
from lib2to3 import pygram, pytree, refactor, fixer_util
11
from lib2to3.tests import support
21
14
class FixerTestCase(support.TestCase):
22
def setUp(self, fix_list=None):
16
# Other test cases can subclass this class and replace "fixer_pkg" with
18
def setUp(self, fix_list=None, fixer_pkg="lib2to3", options=None):
23
19
if fix_list is None:
24
20
fix_list = [self.fixer]
25
options = {"print_function" : False}
26
self.refactor = support.get_refactorer(fix_list, options)
21
self.refactor = support.get_refactorer(fixer_pkg, fix_list, options)
27
22
self.fixer_log = []
28
self.filename = "<string>"
23
self.filename = u"<string>"
30
25
for fixer in chain(self.refactor.pre_order,
31
26
self.refactor.post_order):
35
30
before = support.reformat(before)
36
31
after = support.reformat(after)
37
32
tree = self.refactor.refactor_string(before, self.filename)
38
self.failUnlessEqual(after, str(tree))
33
self.assertEqual(after, unicode(tree))
41
36
def check(self, before, after, ignore_warnings=False):
42
37
tree = self._check(before, after)
43
self.failUnless(tree.was_changed)
38
self.assertTrue(tree.was_changed)
44
39
if not ignore_warnings:
45
self.failUnlessEqual(self.fixer_log, [])
40
self.assertEqual(self.fixer_log, [])
47
42
def warns(self, before, after, message, unchanged=False):
48
43
tree = self._check(before, after)
49
self.failUnless(message in "".join(self.fixer_log))
44
self.assertTrue(message in "".join(self.fixer_log))
51
self.failUnless(tree.was_changed)
46
self.assertTrue(tree.was_changed)
53
48
def warns_unchanged(self, before, message):
54
49
self.warns(before, before, message, unchanged=True)
56
51
def unchanged(self, before, ignore_warnings=False):
57
52
self._check(before, before)
58
53
if not ignore_warnings:
59
self.failUnlessEqual(self.fixer_log, [])
54
self.assertEqual(self.fixer_log, [])
61
56
def assert_runs_after(self, *names):
62
57
fixes = [self.fixer]
63
58
fixes.extend(names)
64
options = {"print_function" : False}
65
r = support.get_refactorer(fixes, options)
59
r = support.get_refactorer("lib2to3", fixes)
66
60
(pre, post) = r.get_fixers()
67
61
n = "fix_" + self.fixer
68
62
if post and post[-1].__class__.__module__.endswith(n):
345
339
a = "from functools import reduce\nreduce(a, b, c)"
342
def test_bug_7253(self):
343
# fix_tuple_params was being bad and orphaning nodes in the tree.
344
b = "def x(arg): reduce(sum, [])"
345
a = "from functools import reduce\ndef x(arg): reduce(sum, [])"
348
348
def test_call_with_lambda(self):
349
349
b = "reduce(lambda x, y: x + y, seq)"
350
350
a = "from functools import reduce\nreduce(lambda x, y: x + y, seq)"
382
382
self.unchanged(s)
384
384
def test_idempotency_print_as_function(self):
385
print_stmt = pygram.python_grammar.keywords.pop("print")
387
s = """print(1, 1+1, 1+1+1)"""
396
pygram.python_grammar.keywords["print"] = print_stmt
385
self.refactor.driver.grammar = pygram.python_grammar_no_print_statement
386
s = """print(1, 1+1, 1+1+1)"""
398
395
def test_1(self):
399
396
b = """print 1, 1+1, 1+1+1"""
464
462
a = """print(file=sys.stderr)"""
467
# With from __future__ import print_function
468
465
def test_with_future_print_function(self):
469
# XXX: These tests won't actually do anything until the parser
470
# is fixed so it won't crash when it sees print(x=y).
471
# When #2412 is fixed, the try/except block can be taken
472
# out and the tests can be run like normal.
473
# MvL: disable entirely for now, so that it doesn't print to stdout
476
s = "from __future__ import print_function\n"\
477
"print('Hai!', end=' ')"
480
b = "print 'Hello, world!'"
481
a = "print('Hello, world!')"
484
s = "from __future__ import *\n"\
485
"print('Hai!', end=' ')"
490
self.assertFalse(True, "#2421 has been fixed -- printing tests "\
491
"need to be updated!")
466
s = "from __future__ import print_function\n" \
467
"print('Hai!', end=' ')"
470
b = "print 'Hello, world!'"
471
a = "print('Hello, world!')"
493
475
class Test_exec(FixerTestCase):
767
def test_one_line_suites(self):
775
except TypeError as e:
782
except TypeError, e: pass
787
except TypeError as e: pass
792
except TypeError, e: pass
796
except TypeError as e: pass
801
except TypeError, e: pass
807
except TypeError as e: pass
785
813
# These should not be touched:
787
815
def test_unchanged_1(self):
1187
1215
a = "[i for i in d. keys( ) ]"
1188
1216
self.check(b, a)
1218
b = "if d. viewkeys ( ) : pass"
1219
a = "if d. keys ( ) : pass"
1222
b = "[i for i in d. viewkeys( ) ]"
1223
a = "[i for i in d. keys( ) ]"
1190
1226
def test_trailing_comment(self):
1191
1227
b = "d.keys() # foo"
1192
1228
a = "list(d.keys()) # foo"
1207
1243
self.check(b, a)
1245
b = """[i for i in d.iterkeys() # foo
1247
a = """[i for i in d.keys() # foo
1251
b = "d.viewitems() # foo"
1252
a = "d.items() # foo"
1209
1255
def test_unchanged(self):
1210
1256
for wrapper in fixer_util.consuming_calls:
1211
1257
s = "s = %s(d.keys())" % wrapper
1339
1385
a = "for x in list(h.keys())[0]: print x"
1340
1386
self.check(b, a)
1399
b = "d.viewvalues()"
1404
b = "[i for i in d.viewkeys()]"
1405
a = "[i for i in d.keys()]"
1409
b = "(i for i in d.viewkeys())"
1410
a = "(i for i in d.keys())"
1414
b = "iter(d.viewkeys())"
1415
a = "iter(d.keys())"
1419
b = "list(d.viewkeys())"
1420
a = "list(d.keys())"
1424
b = "sorted(d.viewkeys())"
1425
a = "sorted(d.keys())"
1342
1428
class Test_xrange(FixerTestCase):
1343
1429
fixer = "xrange"
1661
1747
for key in ('dbhash', 'dumbdbm', 'dbm', 'gdbm'):
1662
1748
self.modules[key] = mapping1[key]
1750
def test_after_local_imports_refactoring(self):
1751
for fix in ("imports", "imports2"):
1753
self.assert_runs_after("import")
1665
1756
class Test_urllib(FixerTestCase):
1666
1757
fixer = "urllib"
1720
1811
for old, changes in self.modules.items():
1721
1812
for new, members in changes:
1722
1813
for member in members:
1814
new_import = ", ".join([n for (n, mems)
1815
in self.modules[old]])
1730
""" % (", ".join([n for (n, mems)
1731
in self.modules[old]]),
1823
""" % (new_import, new, member)
1828
""" % (old, old, member, old, member)
1832
""" % (new_import, new, member, new, member)
1733
1833
self.check(b, a)
2640
2740
class Test_unicode(FixerTestCase):
2641
2741
fixer = "unicode"
2743
def test_whitespace(self):
2744
b = """unicode( x)"""
2748
b = """ unicode(x )"""
2643
2756
def test_unicode_call(self):
2644
2757
b = """unicode(x, y, z)"""
2645
2758
a = """str(x, y, z)"""
2646
2759
self.check(b, a)
2761
def test_unichr(self):
2762
b = """unichr(u'h')"""
2648
2766
def test_unicode_literal_1(self):
2666
2784
def test_prefix_preservation(self):
2667
2785
b = """callable( x)"""
2668
a = """hasattr( x, '__call__')"""
2786
a = """import collections\nisinstance( x, collections.Callable)"""
2669
2787
self.check(b, a)
2671
2789
b = """if callable(x): pass"""
2672
a = """if hasattr(x, '__call__'): pass"""
2790
a = """import collections
2791
if isinstance(x, collections.Callable): pass"""
2673
2792
self.check(b, a)
2675
2794
def test_callable_call(self):
2676
2795
b = """callable(x)"""
2677
a = """hasattr(x, '__call__')"""
2796
a = """import collections\nisinstance(x, collections.Callable)"""
2799
def test_global_import(self):
2802
callable(foo)"""[1:]
2806
isinstance(foo, collections.Callable)"""[1:]
2812
callable(foo)"""[1:]
2813
# same output if it was already imported
2817
from collections import *
2819
callable(foo)"""[1:]
2821
from collections import *
2824
isinstance(foo, collections.Callable)"""[1:]
2829
do_some_other_stuff()
2830
assert callable(do_stuff)"""[1:]
2834
do_some_other_stuff()
2835
assert isinstance(do_stuff, collections.Callable)"""[1:]
2839
if isinstance(do_stuff, Callable):
2840
assert callable(do_stuff)
2842
if not callable(do_stuff):
2845
assert callable(do_stuff)
2847
assert not callable(do_stuff)"""[1:]
2850
if isinstance(do_stuff, Callable):
2851
assert isinstance(do_stuff, collections.Callable)
2853
if not isinstance(do_stuff, collections.Callable):
2856
assert isinstance(do_stuff, collections.Callable)
2858
assert not isinstance(do_stuff, collections.Callable)"""[1:]
2678
2859
self.check(b, a)
2680
2861
def test_callable_should_not_change(self):
2789
2970
a = """x = list(map(f, 'abc')) # foo"""
2790
2971
self.check(b, a)
2973
def test_None_with_multiple_arguments(self):
2974
s = """x = map(None, a, b, c)"""
2975
self.warns_unchanged(s, "cannot convert map(None, ...) with "
2976
"multiple arguments")
2792
2978
def test_map_basic(self):
2793
2979
b = """x = map(f, 'abc')"""
2794
2980
a = """x = list(map(f, 'abc'))"""
2802
2988
a = """x = list('abc')"""
2803
2989
self.check(b, a)
2805
b = """x = map(None, 'abc', 'def')"""
2806
a = """x = list(map(None, 'abc', 'def'))"""
2809
2991
b = """x = map(lambda x: x+1, range(4))"""
2810
2992
a = """x = [x+1 for x in range(4)]"""
2811
2993
self.check(b, a)
3404
3631
a = "from itertools import bar as bang"
3405
3632
self.check(b, a)
3634
b = "from itertools import izip as _zip, imap, bar"
3635
a = "from itertools import bar"
3638
b = "from itertools import imap as _map"
3642
b = "from itertools import imap as _map, izip as _zip"
3407
3646
s = "from itertools import bar as bang"
3408
3647
self.unchanged(s)
3460
3700
self.always_exists = False
3461
3701
self.present_files = set(['__init__.py'])
3462
expected_extensions = ('.py', os.path.pathsep, '.pyc', '.so',
3702
expected_extensions = ('.py', os.path.sep, '.pyc', '.so', '.sl', '.pyd')
3464
3703
names_to_test = (p("/spam/eggs.py"), "ni.py", p("../../shrubbery.py"))
3466
3705
for name in names_to_test:
3490
3729
self.present_files = set(["__init__.py", "bar.py"])
3491
3730
self.check(b, a)
3732
def test_import_from_package(self):
3734
a = "from . import bar"
3735
self.always_exists = False
3736
self.present_files = set(["__init__.py", "bar" + os.path.sep])
3493
3739
def test_comments_and_indent(self):
3494
3740
b = "import bar # Foo"
3495
3741
a = "from . import bar # Foo"
4018
4264
self.check(b, a)
4021
if __name__ == "__main__":
4023
support.run_all_tests(__main__)
4267
class Test_operator(FixerTestCase):
4271
def test_operator_isCallable(self):
4272
b = "operator.isCallable(x)"
4273
a = "hasattr(x, '__call__')"
4276
def test_operator_sequenceIncludes(self):
4277
b = "operator.sequenceIncludes(x, y)"
4278
a = "operator.contains(x, y)"
4281
def test_bare_isCallable(self):
4283
self.warns_unchanged(s, "You should use hasattr(x, '__call__') here.")
4285
def test_bare_sequenceIncludes(self):
4286
s = "sequenceIncludes(x, y)"
4287
self.warns_unchanged(s, "You should use operator.contains here.")