3to2-1.1.1/0000775000000000000000000000000012555622334011010 5ustar rootroot3to2-1.1.1/lib3to2/0000775000000000000000000000000012555622334012266 5ustar rootroot3to2-1.1.1/lib3to2/tests/0000775000000000000000000000000012555622334013430 5ustar rootroot3to2-1.1.1/lib3to2/tests/__init__.py0000666000000000000000000000000712513000130015512 0ustar rootroot#empty 3to2-1.1.1/lib3to2/tests/test_with.py0000666000000000000000000000067612513010502016005 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_with(lib3to2FixerTestCase): fixer = "with" def test_with_oneline(self): b = "with a as b: pass" a = "from __future__ import with_statement\nwith a as b: pass" self.check(b, a) def test_with_suite(self): b = "with a as b:\n pass" a = "from __future__ import with_statement\nwith a as b:\n pass" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_unpacking.py0000666000000000000000000000474212513010502017007 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_unpacking(lib3to2FixerTestCase): fixer = 'unpacking' def test_unchanged(self): s = "def f(*args): pass" self.unchanged(s) s = "for i in range(s): pass" self.unchanged(s) s = "a, b, c = range(100)" self.unchanged(s) def test_forloop(self): b = """ for a, b, c, *d, e in two_dim_array: pass""" a = """ for _3to2iter in two_dim_array: _3to2list = list(_3to2iter) a, b, c, d, e, = _3to2list[:3] + [_3to2list[3:-1]] + _3to2list[-1:] pass""" self.check(b, a) b = """ for a, b, *c in some_thing: do_stuff""" a = """ for _3to2iter in some_thing: _3to2list = list(_3to2iter) a, b, c, = _3to2list[:2] + [_3to2list[2:]] do_stuff""" self.check(b, a) b = """ for *a, b, c, d, e, f, g in some_thing: pass""" a = """ for _3to2iter in some_thing: _3to2list = list(_3to2iter) a, b, c, d, e, f, g, = [_3to2list[:-6]] + _3to2list[-6:] pass""" self.check(b, a) def test_assignment(self): b = """ a, *b, c = range(100)""" a = """ _3to2list = list(range(100)) a, b, c, = _3to2list[:1] + [_3to2list[1:-1]] + _3to2list[-1:]""" self.check(b, a) b = """ a, b, c, d, *e, f, g = letters""" a = """ _3to2list = list(letters) a, b, c, d, e, f, g, = _3to2list[:4] + [_3to2list[4:-2]] + _3to2list[-2:]""" self.check(b, a) b = """ *e, f, g = letters""" a = """ _3to2list = list(letters) e, f, g, = [_3to2list[:-2]] + _3to2list[-2:]""" self.check(b, a) b = """ a, b, c, d, *e = stuff""" a = """ _3to2list = list(stuff) a, b, c, d, e, = _3to2list[:4] + [_3to2list[4:]]""" self.check(b, a) b = """ *z, = stuff""" a = """ _3to2list = list(stuff) z, = [_3to2list[:]]""" self.check(b, a) b = """ while True: a, *b, c = stuff other_stuff = make_more_stuff(a, b, c)""" a = """ while True: _3to2list = list(stuff) a, b, c, = _3to2list[:1] + [_3to2list[1:-1]] + _3to2list[-1:] other_stuff = make_more_stuff(a, b, c)""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_unittest.py0000666000000000000000000000130712513010502016701 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_unittest(lib3to2FixerTestCase): fixer = 'unittest' def test_imported(self): b = "import unittest" a = "import unittest2" self.check(b, a) def test_used(self): b = "unittest.AssertStuff(True)" a = "unittest2.AssertStuff(True)" self.check(b, a) def test_from_import(self): b = "from unittest import *" a = "from unittest2 import *" self.check(b, a) def test_imported_from(self): s = "from whatever import unittest" self.unchanged(s) def test_not_base(self): s = "not_unittest.unittest.stuff()" self.unchanged(s) 3to2-1.1.1/lib3to2/tests/test_throw.py0000666000000000000000000000364012513010502016167 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_throw(lib3to2FixerTestCase): fixer = 'throw' def test_unchanged(self): """ Due to g.throw(E(V)) being valid in 2.5, this fixer fortunately doesn't need to touch code that constructs exception objects without explicit tracebacks. """ s = """g.throw(E(V))""" self.unchanged(s) s = """omg.throw(E("What?"))""" self.unchanged(s) def test_what_doesnt_work(self): """ These tests should fail, but don't. TODO: Uncomment successfully. One potential way of making these work is a separate fix_exceptions with a lower run order than fix_throw, to communicate to fix_throw how to sort out that third argument. These items are currently outside the scope of 3to2. """ b = """ E = BaseException(V).with_traceback(T) gen.throw(E) """ #a = """ #E = BaseException(V) #gen.throw(E, V, T) #""" #self.check(b, a) self.unchanged(b) b = """ E = BaseException(V) E.__traceback__ = S E.__traceback__ = T gen.throw(E) """ #a = """ #E = BaseException(V) #gen.throw(E, V, T) #self.check(b, a) self.unchanged(b) def test_traceback(self): """ This stuff currently works, and is the opposite counterpart to the 2to3 version of fix_throw. """ b = """myGen.throw(E(V).with_traceback(T))""" a = """myGen.throw(E, V, T)""" self.check(b, a) b = """fling.throw(E().with_traceback(T))""" a = """fling.throw(E, None, T)""" self.check(b, a) b = """myVar.throw(E("Sorry, you cannot do that.").with_traceback(T))""" a = """myVar.throw(E, "Sorry, you cannot do that.", T)""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_super.py0000666000000000000000000000255112513010502016162 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_super(lib3to2FixerTestCase): fixer = "super" def test_noargs(self): b = "def m(self):\n super()" a = "def m(self):\n super(self.__class__, self)" self.check(b, a) def test_other_params(self): b = "def m(a, self=None):\n super()" a = "def m(a, self=None):\n super(a.__class__, a)" self.check(b, a) def test_no_with_stars(self): s = "def m(*args, **kwargs):\n super()" self.unchanged(s, ignore_warnings=True) def test_no_with_noargs(self): s = "def m():\n super()" self.unchanged(s, ignore_warnings=True) def test_class_noargs(self): b = "class c:\n def m(self):\n super()" a = "class c:\n def m(self):\n super(c, self)" self.check(b, a) def test_class_other_params(self): b = "class c:\n def m(a, self=None):\n super()" a = "class c:\n def m(a, self=None):\n super(c, a)" self.check(b, a) def test_class_no_with_stars(self): s = "class c:\n def m(*args, **kwargs):\n super()" self.unchanged(s, ignore_warnings=True) def test_class_no_with_noargs(self): s = "class c:\n def m():\n super()" self.unchanged(s, ignore_warnings=True) 3to2-1.1.1/lib3to2/tests/test_str.py0000666000000000000000000000125112513010502015630 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_str(lib3to2FixerTestCase): fixer = "str" def test_str_call(self): b = """str(x, y, z)""" a = """unicode(x, y, z)""" self.check(b, a) def test_chr_call(self): b = """chr(a, t, m)""" a = """unichr(a, t, m)""" self.check(b, a) def test_str_literal_1(self): b = '''"x"''' a = '''u"x"''' self.check(b, a) def test_str_literal_2(self): b = """r'x'""" a = """ur'x'""" self.check(b, a) def test_str_literal_3(self): b = """R'''x'''""" a = """uR'''x'''""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_setliteral.py0000666000000000000000000000273012513010502017173 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_setliteral(lib3to2FixerTestCase): fixer = "setliteral" def test_unchanged_dict(self): s = """{"ghoul": 100, "zombie": 50, "gremlin": 40}""" self.unchanged(s) s = """{1: "spider", 2: "hills", 3: "bologna", None: "tapeworm"}""" self.unchanged(s) s = """{}""" self.unchanged(s) s = """{'a':'b'}""" self.unchanged(s) def test_simple_literal(self): b = """{'Rm 101'}""" a = """set(['Rm 101'])""" self.check(b, a) def test_multiple_items(self): b = """{'Rm 101', 'Rm 102', spam, ham, eggs}""" a = """set(['Rm 101', 'Rm 102', spam, ham, eggs])""" self.check(b, a) b = """{ a, b, c, d, e}""" a = """set([ a, b, c, d, e])""" self.check(b, a) def test_simple_set_comprehension(self): b = """{x for x in range(256)}""" a = """set([x for x in range(256)])""" self.check(b, a) def test_complex_set_comprehension(self): b = """{F(x) for x in range(256) if x%2}""" a = """set([F(x) for x in range(256) if x%2])""" self.check(b, a) b = """{(lambda x: 2000 + x)(x) for x, y in {(5, 400), (6, 600), (7, 900), (8, 1125), (9, 1000)}}""" a = """set([(lambda x: 2000 + x)(x) for x, y in set([(5, 400), (6, 600), (7, 900), (8, 1125), (9, 1000)])])""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_reduce.py0000666000000000000000000000245512513010502016276 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_reduce(lib3to2FixerTestCase): fixer = "reduce" def test_functools_import(self): b = """ from functools import reduce reduce(f, it)""" a = """ reduce(f, it)""" self.check(b, a) b = """ do_other_stuff; from functools import reduce reduce(f, it)""" a = """ do_other_stuff reduce(f, it)""" self.check(b, a) b = """ do_other_stuff; from functools import reduce; do_more_stuff reduce(f, it)""" a = """ do_other_stuff; do_more_stuff reduce(f, it)""" self.check(b, a) def test_functools_reduce(self): b = """ import functools functools.reduce(spam, ['spam', 'spam', 'baked beans', 'spam']) """ a = """ import functools reduce(spam, ['spam', 'spam', 'baked beans', 'spam']) """ self.check(b, a) def test_prefix(self): b = """ a = functools.reduce( self.thing, self.children , f( 3 )) """ a = """ a = reduce( self.thing, self.children , f( 3 )) """ self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_range.py0000666000000000000000000000350612513010502016121 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_range(lib3to2FixerTestCase): fixer = "range" def test_notbuiltin_list(self): b = "x.list(range(10))" a = "x.list(xrange(10))" self.check(b, a) def test_prefix_preservation(self): b = """x = range( 10 )""" a = """x = xrange( 10 )""" self.check(b, a) b = """x = range( 1 , 10 )""" a = """x = xrange( 1 , 10 )""" self.check(b, a) b = """x = range( 0 , 10 , 2 )""" a = """x = xrange( 0 , 10 , 2 )""" self.check(b, a) def test_single_arg(self): b = """x = range(10)""" a = """x = xrange(10)""" self.check(b, a) def test_two_args(self): b = """x = range(1, 10)""" a = """x = xrange(1, 10)""" self.check(b, a) def test_three_args(self): b = """x = range(0, 10, 2)""" a = """x = xrange(0, 10, 2)""" self.check(b, a) def test_wrapped_in_list(self): b = """x = list(range(10, 3, 9))""" a = """x = range(10, 3, 9)""" self.check(b, a) b = """x = foo(list(range(10, 3, 9)))""" a = """x = foo(range(10, 3, 9))""" self.check(b, a) b = """x = list(range(10, 3, 9)) + [4]""" a = """x = range(10, 3, 9) + [4]""" self.check(b, a) b = """x = list(range(10))[::-1]""" a = """x = range(10)[::-1]""" self.check(b, a) b = """x = list(range(10)) [3]""" a = """x = range(10) [3]""" self.check(b, a) def test_range_in_for(self): b = """for i in range(10):\n j=i""" a = """for i in xrange(10):\n j=i""" self.check(b, a) b = """[i for i in range(10)]""" a = """[i for i in xrange(10)]""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_raise.py0000666000000000000000000000441712513010502016132 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_raise(lib3to2FixerTestCase): fixer = 'raise' def test_unchanged(self): """ Due to raise E(V) being valid in 2.5, this fixer fortunately doesn't need to touch code that constructs exception objects without explicit tracebacks. """ s = """raise E(V)""" self.unchanged(s) s = """raise E("What?")""" self.unchanged(s) s = """raise""" self.unchanged(s) def test_what_doesnt_work(self): """ These tests should fail, but don't. TODO: Uncomment successfully. One potential way of making these work is a separate fix_exceptions with a lower run order than fix_raise, to communicate to fix_raise how to sort out that third argument. These items are currently outside the scope of 3to2. """ b = """ E = BaseException(V).with_traceback(T) raise E """ #a = """ #E = BaseException(V) #raise E, V, T #""" #self.check(b, a) self.unchanged(b) b = """ E = BaseException(V) E.__traceback__ = S E.__traceback__ = T raise E """ #a = """ #E = BaseException(V) #raise E, V, T #self.check(b, a) self.unchanged(b) def test_traceback(self): """ This stuff currently works, and is the opposite counterpart to the 2to3 version of fix_raise. """ b = """raise E(V).with_traceback(T)""" a = """raise E, V, T""" self.check(b, a) b = """raise E().with_traceback(T)""" a = """raise E, None, T""" self.check(b, a) b = """raise E("Sorry, you cannot do that.").with_traceback(T)""" a = """raise E, "Sorry, you cannot do that.", T""" self.check(b, a) def test_chain(self): b = "raise E(V).with_traceback(t) from exc" a = "raise E, V, t" self.check(b, a, ignore_warnings=True) b = "raise E(V) from exc" a = "raise E(V)" self.check(b, a, ignore_warnings=True) b = "raise eBob.exception from exc" a = "raise eBob.exception" self.check(b, a, ignore_warnings=True) 3to2-1.1.1/lib3to2/tests/test_printfunction.py0000666000000000000000000000272412513010502017730 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_printfunction(lib3to2FixerTestCase): fixer = "printfunction" def test_generic(self): b = """print()""" a = """from __future__ import print_function\nprint()""" self.check(b,a) def test_literal(self): b = """print('spam')""" a = """from __future__ import print_function\nprint('spam')""" self.check(b,a) def test_not_builtin_unchanged(self): s = "this.shouldnt.be.changed.because.it.isnt.builtin.print()" self.unchanged(s) #XXX: Quoting this differently than triple-quotes, because with newline #XXX: setting, I can't quite get the triple-quoted versions to line up. def test_arbitrary_printing(self): b = "import dinosaur.skull\nimport sys\nprint"\ "(skull.jaw, skull.jaw.biteforce, file=sys.stderr)" a = "from __future__ import print_function\n"\ "import dinosaur.skull\nimport sys\nprint"\ "(skull.jaw, skull.jaw.biteforce, file=sys.stderr)" self.check(b, a) def test_long_arglist(self): b = "print(spam, spam, spam, spam, spam, baked_beans, spam, spam,"\ "spam, spam, sep=', spam, ', end=wonderful_spam)\nprint()" a = "from __future__ import print_function\n"\ "print(spam, spam, spam, spam, spam, baked_beans, spam, spam,"\ "spam, spam, sep=', spam, ', end=wonderful_spam)\nprint()" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_print.py0000666000000000000000000000334112513010502016156 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_print(lib3to2FixerTestCase): fixer = "print" def test_generic(self): b = """print()""" a = """print""" self.check(b,a) def test_literal(self): b = """print('spam')""" a = """print 'spam'""" self.check(b,a) def test_not_builtin_unchanged(self): s = "this.shouldnt.be.changed.because.it.isnt.builtin.print()" self.unchanged(s) #XXX: Quoting this differently than triple-quotes, because with newline #XXX: setting, I can't quite get the triple-quoted versions to line up. def test_arbitrary_printing(self): b = "import dinosaur.skull\nimport sys\nprint"\ "(skull.jaw, skull.jaw.biteforce, file=sys.stderr)" a = "import dinosaur.skull\nimport sys\nprint "\ ">>sys.stderr, skull.jaw, skull.jaw.biteforce" self.check(b, a) def test_long_arglist(self): b = "print(spam, spam, spam, spam, spam, baked_beans, spam, spam,"\ " spam, spam, sep=', spam, ', end=wonderful_spam)\nprint()" a = "import sys\nprint ', spam, '.join([unicode(spam), unicode(spam), unicode(spam), unicode(spam), unicode(spam), unicode(baked_beans),"\ " unicode(spam), unicode(spam), unicode(spam), unicode(spam)]),; sys.stdout.write(wonderful_spam)\nprint" self.check(b, a, ignore_warnings=True) def test_nones(self): b = "print(1,2,3,end=None, sep=None, file=None)" a = "print 1,2,3" self.check(b, a) def test_argument_unpacking(self): s = "print(*args)" self.warns_unchanged(s, "-fprint does not support argument unpacking. fix using -xprint and then again with -fprintfunction.") 3to2-1.1.1/lib3to2/tests/test_open.py0000666000000000000000000000067112513010502015766 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_open(lib3to2FixerTestCase): fixer = "open" def test_imports(self): b = """new_file = open("some_filename", newline="\\r")""" a = """from io import open\nnew_file = open("some_filename", newline="\\r")""" self.check(b, a) def test_doesnt_import(self): s = """new_file = nothing.open("some_filename")""" self.unchanged(s) 3to2-1.1.1/lib3to2/tests/test_numliterals.py0000666000000000000000000000233212513010502017360 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_numliterals(lib3to2FixerTestCase): fixer = "numliterals" def test_octal_1(self): b = """0o755""" a = """0755""" self.check(b, a) def test_octal_2(self): b = """0o777""" a = """0777""" self.check(b, a) def test_bin_1(self): b = """0b10010110""" a = """__builtins__.long("10010110", 2)""" self.check(b, a) def test_bin_2(self): b = """spam(0b1101011010110)""" a = """spam(__builtins__.long("1101011010110", 2))""" self.check(b, a) def test_comments_and_spacing_2(self): b = """b = 0o755 # spam""" a = """b = 0755 # spam""" self.check(b, a) def test_unchanged_str(self): s = """'0x1400'""" self.unchanged(s) s = """'0b011000'""" self.unchanged(s) s = """'0o755'""" self.unchanged(s) def test_unchanged_other(self): s = """5.0""" self.unchanged(s) s = """5.0e10""" self.unchanged(s) s = """5.4 + 4.9j""" self.unchanged(s) s = """4j""" self.unchanged(s) s = """4.4j""" self.unchanged(s) 3to2-1.1.1/lib3to2/tests/test_next.py0000666000000000000000000001074212513010502016003 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_next(lib3to2FixerTestCase): fixer = "next" def test_1(self): b = """next(it)""" a = """it.next()""" self.check(b, a) def test_2(self): b = """next(a.b.c.d)""" a = """a.b.c.d.next()""" self.check(b, a) def test_3(self): b = """next((a + b))""" a = """(a + b).next()""" self.check(b, a) def test_4(self): b = """next(a())""" a = """a().next()""" self.check(b, a) def test_5(self): b = """next(a()) + b""" a = """a().next() + b""" self.check(b, a) def test_6(self): b = """c( next(a()) + b)""" a = """c( a().next() + b)""" self.check(b, a) def test_prefix_preservation_1(self): b = """ for a in b: foo(a) next(a) """ a = """ for a in b: foo(a) a.next() """ self.check(b, a) def test_prefix_preservation_2(self): b = """ for a in b: foo(a) # abc # def next(a) """ a = """ for a in b: foo(a) # abc # def a.next() """ self.check(b, a) def test_prefix_preservation_3(self): b = """ next = 5 for a in b: foo(a) a.__next__() """ a = """ next = 5 for a in b: foo(a) a.next() """ self.check(b, a) def test_prefix_preservation_4(self): b = """ next = 5 for a in b: foo(a) # abc # def a.__next__() """ a = """ next = 5 for a in b: foo(a) # abc # def a.next() """ self.check(b, a) def test_prefix_preservation_5(self): b = """ next = 5 for a in b: foo(foo(a), # abc a.__next__()) """ a = """ next = 5 for a in b: foo(foo(a), # abc a.next()) """ self.check(b, a) def test_prefix_preservation_6(self): b = """ for a in b: foo(foo(a), # abc next(a)) """ a = """ for a in b: foo(foo(a), # abc a.next()) """ self.check(b, a) def test_method_1(self): b = """ class A: def __next__(self): pass """ a = """ class A: def next(self): pass """ self.check(b, a) def test_method_2(self): b = """ class A(object): def __next__(self): pass """ a = """ class A(object): def next(self): pass """ self.check(b, a) def test_method_3(self): b = """ class A: def __next__(x): pass """ a = """ class A: def next(x): pass """ self.check(b, a) def test_method_4(self): b = """ class A: def __init__(self, foo): self.foo = foo def __next__(self): pass def __iter__(self): return self """ a = """ class A: def __init__(self, foo): self.foo = foo def next(self): pass def __iter__(self): return self """ self.check(b, a) def test_noncall_access_1(self): b = """gnext = g.__next__""" a = """gnext = g.next""" self.check(b, a) def test_noncall_access_2(self): b = """f(g.__next__ + 5)""" a = """f(g.next + 5)""" self.check(b, a) def test_noncall_access_3(self): b = """f(g().__next__ + 5)""" a = """f(g().next + 5)""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_newstyle.py0000666000000000000000000000066712513010502016704 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_newstyle(lib3to2FixerTestCase): fixer = "newstyle" def test_oneline(self): b = """class Foo: pass""" a = """class Foo(object): pass""" self.check(b, a) def test_suite(self): b = """ class Foo(): do_stuff()""" a = """ class Foo(object): do_stuff()""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_methodattrs.py0000666000000000000000000000127312513010502017362 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_methodattrs(lib3to2FixerTestCase): fixer = "methodattrs" attrs = ["func", "self"] def test_methodattrs(self): for attr in self.attrs: b = "a.__%s__" % attr a = "a.im_%s" % attr self.check(b, a) b = "self.foo.__%s__.foo_bar" % attr a = "self.foo.im_%s.foo_bar" % attr self.check(b, a) b = "dir(self.foo.__self__.__class__)" a = "dir(self.foo.im_self.__class__)" self.check(b, a) def test_unchanged(self): for attr in self.attrs: s = "foo(__%s__ + 5)" % attr self.unchanged(s) 3to2-1.1.1/lib3to2/tests/test_metaclass.py0000666000000000000000000000766312513010502017011 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_metaclass(lib3to2FixerTestCase): fixer = 'metaclass' def test_unchanged(self): self.unchanged("class X(): pass") self.unchanged("class X(object): pass") self.unchanged("class X(object1, object2): pass") self.unchanged("class X(object1, object2, object3): pass") s = """ class X(): def __metaclass__(self): pass """ self.unchanged(s) s = """ class X(): a[23] = 74 """ self.unchanged(s) def test_comments(self): a = """ class X(object): # hi __metaclass__ = AppleMeta pass """ b = """ class X(metaclass=AppleMeta): # hi pass """ self.check(b, a) a = """ class X(object): __metaclass__ = Meta pass # Bedtime! """ b = """ class X(metaclass=Meta): pass # Bedtime! """ self.check(b, a) def test_meta_noparent_odd_body(self): # no-parent class, odd body a = """ class X(object): __metaclass__ = Q pass """ b = """ class X(metaclass=Q): pass """ self.check(b, a) def test_meta_oneparent_no_body(self): # one parent class, no body a = """ class X(object): __metaclass__ = Q pass""" b = """ class X(object, metaclass=Q): pass""" self.check(b, a) def test_meta_oneparent_simple_body_1(self): # one parent, simple body a = """ class X(object): __metaclass__ = Meta bar = 7 """ b = """ class X(object, metaclass=Meta): bar = 7 """ self.check(b, a) def test_meta_oneparent_simple_body_2(self): a = """ class X(object): __metaclass__ = Meta x = 4; g = 23 """ b = """ class X(metaclass=Meta): x = 4; g = 23 """ self.check(b, a) def test_meta_oneparent_simple_body_3(self): a = """ class X(object): __metaclass__ = Meta bar = 7 """ b = """ class X(object, metaclass=Meta): bar = 7 """ self.check(b, a) def test_meta_multiparent_simple_body_1(self): # multiple inheritance, simple body a = """ class X(clsA, clsB): __metaclass__ = Meta bar = 7 """ b = """ class X(clsA, clsB, metaclass=Meta): bar = 7 """ self.check(b, a) def test_meta_multiparent_simple_body_2(self): # keywords in the class statement a = """ class m(a, arg=23): __metaclass__ = Meta pass""" b = """ class m(a, arg=23, metaclass=Meta): pass""" self.check(b, a) def test_meta_expression_simple_body_1(self): a = """ class X(expression(2 + 4)): __metaclass__ = Meta pass """ b = """ class X(expression(2 + 4), metaclass=Meta): pass """ self.check(b, a) def test_meta_expression_simple_body_2(self): a = """ class X(expression(2 + 4), x**4): __metaclass__ = Meta pass """ b = """ class X(expression(2 + 4), x**4, metaclass=Meta): pass """ self.check(b, a) def test_meta_noparent_simple_body(self): a = """ class X(object): __metaclass__ = Meta save.py = 23 out = 5 """ b = """ class X(metaclass=Meta): save.py = 23 out = 5 """ self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_memoryview.py0000666000000000000000000000125412513010502017226 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_memoryview(lib3to2FixerTestCase): fixer = "memoryview" def test_simple(self): b = """x = memoryview(y)""" a = """x = buffer(y)""" self.check(b, a) def test_slicing(self): b = """x = memoryview(y)[1:4]""" a = """x = buffer(y)[1:4]""" self.check(b, a) def test_prefix_preservation(self): b = """x = memoryview( y )[1:4]""" a = """x = buffer( y )[1:4]""" self.check(b, a) def test_nested(self): b = """x = list(memoryview(y)[1:4])""" a = """x = list(buffer(y)[1:4])""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_kwargs.py0000666000000000000000000000747312513010502016332 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_kwargs(lib3to2FixerTestCase): fixer = 'kwargs' def test_basic_unchanged(self): s = """ def spam(ham, eggs): funky()""" self.unchanged(s) def test_args_kwargs_unchanged(self): s = """ def spam(ham, *args, **kwargs): funky()""" self.unchanged(s) def test_args_named_pos(self): b = """ def spam(ham, *args, eggs, monkeys): funky()""" a = """ def spam(ham, *args, **_3to2kwargs): monkeys = _3to2kwargs['monkeys']; del _3to2kwargs['monkeys'] eggs = _3to2kwargs['eggs']; del _3to2kwargs['eggs'] funky()""" self.check(b, a) def test_args_named_pos_catchall(self): b = """ def spam(ham, *args, eggs, monkeys, **stuff): funky()""" a = """ def spam(ham, *args, **stuff): monkeys = stuff['monkeys']; del stuff['monkeys'] eggs = stuff['eggs']; del stuff['eggs'] funky()""" self.check(b, a) def test_bare_star_named(self): b = """ def spam(ham, *, eggs, monkeys): funky()""" a = """ def spam(ham, **_3to2kwargs): monkeys = _3to2kwargs['monkeys']; del _3to2kwargs['monkeys'] eggs = _3to2kwargs['eggs']; del _3to2kwargs['eggs'] funky()""" self.check(b, a) def test_bare_star_named_simple_defaults(self): b = """ def spam(ham, *, dinosaurs, eggs=3, monkeys=2): funky()""" a = """ def spam(ham, **_3to2kwargs): if 'monkeys' in _3to2kwargs: monkeys = _3to2kwargs['monkeys']; del _3to2kwargs['monkeys'] else: monkeys = 2 if 'eggs' in _3to2kwargs: eggs = _3to2kwargs['eggs']; del _3to2kwargs['eggs'] else: eggs = 3 dinosaurs = _3to2kwargs['dinosaurs']; del _3to2kwargs['dinosaurs'] funky()""" self.check(b, a) def test_bare_star_named_simple_defaults_catchall(self): b = """ def spam(ham, *, dinosaurs, eggs=3, monkeys=2, **stuff): funky()""" a = """ def spam(ham, **stuff): if 'monkeys' in stuff: monkeys = stuff['monkeys']; del stuff['monkeys'] else: monkeys = 2 if 'eggs' in stuff: eggs = stuff['eggs']; del stuff['eggs'] else: eggs = 3 dinosaurs = stuff['dinosaurs']; del stuff['dinosaurs'] funky()""" self.check(b, a) def test_bare_star_named_complicated_defaults(self): b = """ def spam(ham, *, dinosaurs, eggs=call_fn(lambda a: b), monkeys=[i.split() for i in something(args)]): funky()""" a = """ def spam(ham, **_3to2kwargs): if 'monkeys' in _3to2kwargs: monkeys = _3to2kwargs['monkeys']; del _3to2kwargs['monkeys'] else: monkeys = [i.split() for i in something(args)] if 'eggs' in _3to2kwargs: eggs = _3to2kwargs['eggs']; del _3to2kwargs['eggs'] else: eggs = call_fn(lambda a: b) dinosaurs = _3to2kwargs['dinosaurs']; del _3to2kwargs['dinosaurs'] funky()""" self.check(b, a) def test_bare_star_named_complicated_defaults_catchall(self): b = """ def spam(ham, *, dinosaurs, eggs=call_fn(lambda a: b), monkeys=[i.split() for i in something(args)], **stuff): funky()""" a = """ def spam(ham, **stuff): if 'monkeys' in stuff: monkeys = stuff['monkeys']; del stuff['monkeys'] else: monkeys = [i.split() for i in something(args)] if 'eggs' in stuff: eggs = stuff['eggs']; del stuff['eggs'] else: eggs = call_fn(lambda a: b) dinosaurs = stuff['dinosaurs']; del stuff['dinosaurs'] funky()""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_itertools.py0000666000000000000000000000215312513010502017046 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_itertoools(lib3to2FixerTestCase): fixer = "itertools" def test_map(self): b = """map(a, b)""" a = """from itertools import imap\nimap(a, b)""" self.check(b, a) def test_unchanged_nobuiltin(self): s = """obj.filter(a, b)""" self.unchanged(s) s = """ def map(): pass """ self.unchanged(s) def test_filter(self): b = "a = filter( a, b)" a = "from itertools import ifilter\na = ifilter( a, b)" self.check(b, a) def test_zip(self): b = """for key, val in zip(a, b):\n\tdct[key] = val""" a = """from itertools import izip\nfor key, val in izip(a, b):\n\tdct[key] = val""" self.check(b, a) def test_filterfalse(self): b = """from itertools import function, filterfalse, other_function""" a = """from itertools import function, ifilterfalse, other_function""" self.check( b, a) b = """filterfalse(a, b)""" a = """ifilterfalse(a, b)""" self.check(b, a ) 3to2-1.1.1/lib3to2/tests/test_intern.py0000666000000000000000000000341312513010502016321 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_intern(lib3to2FixerTestCase): fixer = "intern" #XXX: Does not remove unused "import sys" lines. def test_prefix_preservation(self): b = """import sys\nx = sys.intern( a )""" a = """import sys\nx = intern( a )""" self.check(b, a) b = """import sys\ny = sys.intern("b" # test )""" a = """import sys\ny = intern("b" # test )""" self.check(b, a) b = """import sys\nz = sys.intern(a+b+c.d, )""" a = """import sys\nz = intern(a+b+c.d, )""" self.check(b, a) def test(self): b = """from sys import intern\nx = intern(a)""" a = """\nx = intern(a)""" self.check(b, a) b = """import sys\nz = sys.intern(a+b+c.d,)""" a = """import sys\nz = intern(a+b+c.d,)""" self.check(b, a) b = """import sys\nsys.intern("y%s" % 5).replace("y", "")""" a = """import sys\nintern("y%s" % 5).replace("y", "")""" self.check(b, a) # These should not be refactored def test_multimports(self): b = """from sys import intern, path""" a = """from sys import path""" self.check(b, a) b = """from sys import path, intern""" a = """from sys import path""" self.check(b, a) b = """from sys import argv, intern, path""" a = """from sys import argv, path""" self.check(b, a) def test_unchanged(self): s = """intern(a=1)""" self.unchanged(s) s = """intern(f, g)""" self.unchanged(s) s = """intern(*h)""" self.unchanged(s) s = """intern(**i)""" self.unchanged(s) s = """intern()""" self.unchanged(s) 3to2-1.1.1/lib3to2/tests/test_int.py0000666000000000000000000000270112513010502015613 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_int(lib3to2FixerTestCase): fixer = "int" def test_1(self): b = """x = int(x)""" a = """x = long(x)""" self.check(b, a) def test_2(self): b = """y = isinstance(x, int)""" a = """y = isinstance(x, long)""" self.check(b, a) def test_unchanged(self): s = """int = True""" self.unchanged(s) s = """s.int = True""" self.unchanged(s) s = """def int(): pass""" self.unchanged(s) s = """class int(): pass""" self.unchanged(s) s = """def f(int): pass""" self.unchanged(s) s = """def f(g, int): pass""" self.unchanged(s) s = """def f(x, int=True): pass""" self.unchanged(s) def test_prefix_preservation(self): b = """x = int( x )""" a = """x = long( x )""" self.check(b, a) def test_literal_1(self): b = """5""" a = """5L""" self.check(b, a) def test_literal_2(self): b = """a = 12""" a = """a = 12L""" self.check(b, a) def test_literal_3(self): b = """0""" a = """0L""" self.check(b, a) def test_complex_1(self): b = """5 + 4j""" a = """5L + 4j""" self.check(b, a) def test_complex_2(self): b = """35 + 2j""" a = """35L + 2j""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_input.py0000666000000000000000000000234612513010502016165 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_input(lib3to2FixerTestCase): fixer = "input" def test_prefix_preservation(self): b = """x = input( )""" a = """x = raw_input( )""" self.check(b, a) b = """x = input( '' )""" a = """x = raw_input( '' )""" self.check(b, a) def test_1(self): b = """x = input()""" a = """x = raw_input()""" self.check(b, a) def test_2(self): b = """x = input('a')""" a = """x = raw_input('a')""" self.check(b, a) def test_3(self): b = """x = input('prompt')""" a = """x = raw_input('prompt')""" self.check(b, a) def test_4(self): b = """x = input(foo(a) + 6)""" a = """x = raw_input(foo(a) + 6)""" self.check(b, a) def test_5(self): b = """x = input(invite).split()""" a = """x = raw_input(invite).split()""" self.check(b, a) def test_6(self): b = """x = input(invite) . split ()""" a = """x = raw_input(invite) . split ()""" self.check(b, a) def test_7(self): b = "x = int(input())" a = "x = int(raw_input())" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_imports2.py0000666000000000000000000001710512513010502016604 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_imports2(lib3to2FixerTestCase): fixer = "imports2" def test_name_usage_simple(self): b = """ import urllib.request urllib.request.urlopen(spam)""" a = """ import urllib2, urllib urllib2.urlopen(spam)""" self.check(b, a) b = """ if True: import http.server else: import this while True: http.server.HTTPServer(('localhost', 80), http.server.SimpleHTTPRequestHandler) else: import urllib.request""" a = """ if True: import CGIHTTPServer, SimpleHTTPServer, BaseHTTPServer else: import this while True: BaseHTTPServer.HTTPServer(('localhost', 80), SimpleHTTPServer.SimpleHTTPRequestHandler) else: import urllib2, urllib""" self.check(b, a) def test_name_scope_def(self): b = """ import urllib.request def importing_stuff(): import urllib.request urllib.request.urlopen(stuff) urllib.request.urlretrieve(stuff)""" a = """ import urllib2, urllib def importing_stuff(): import urllib2, urllib urllib2.urlopen(stuff) urllib.urlretrieve(stuff)""" self.check(b, a) b = """ import math, urllib.request, http.server, dbm w = dbm.whichdb() g = dbm.gnu() a = dbm.open()""" a = """ import math import anydbm, whichdb, dbm import CGIHTTPServer, SimpleHTTPServer, BaseHTTPServer import urllib2, urllib w = whichdb.whichdb() g = dbm.gnu() a = anydbm.open()""" self.check(b, a) def test_name_scope_if(self): b = """ if thing: import http.server elif other_thing: import xmlrpc.server if related_thing: myServ = http.server.HTTPServer(('localhost', '80'), http.server.CGIHTTPRequestHandler) elif other_related_thing: myServ = xmlrpc.server.SimpleXMLRPCServer(('localhost', '80'), CGIXMLRPCRequestHandler) # just for kicks... monkey_wrench_in_the_works = http.server.SimpleHTTPRequestHandler""" a = """ if thing: import CGIHTTPServer, SimpleHTTPServer, BaseHTTPServer elif other_thing: import DocXMLRPCServer, SimpleXMLRPCServer if related_thing: myServ = BaseHTTPServer.HTTPServer(('localhost', '80'), CGIHTTPServer.CGIHTTPRequestHandler) elif other_related_thing: myServ = SimpleXMLRPCServer.SimpleXMLRPCServer(('localhost', '80'), CGIXMLRPCRequestHandler) # just for kicks... monkey_wrench_in_the_works = SimpleHTTPServer.SimpleHTTPRequestHandler""" self.check(b, a) def test_name_scope_try_except(self): b = """ try: import http.server except ImportError: import xmlrpc.server # some time has passed, and we know that http.server was bad. srv = xmlrpc.server.DocXMLRPCServer(addr, xmlrpc.server.DocCGIXMLRPCRequestHandler) # some more time has passed, and we know that http.server is good. srv = http.server.HTTPServer(addr, http.server.CGIHTTPRequestHandler)""" a = """ try: import CGIHTTPServer, SimpleHTTPServer, BaseHTTPServer except ImportError: import DocXMLRPCServer, SimpleXMLRPCServer # some time has passed, and we know that http.server was bad. srv = DocXMLRPCServer.DocXMLRPCServer(addr, DocXMLRPCServer.DocCGIXMLRPCRequestHandler) # some more time has passed, and we know that http.server is good. srv = BaseHTTPServer.HTTPServer(addr, CGIHTTPServer.CGIHTTPRequestHandler)""" self.check(b, a) def test_name_multiple_imports(self): b = """ import math, http.server, urllib.request, string""" a = """ import math, string import urllib2, urllib import CGIHTTPServer, SimpleHTTPServer, BaseHTTPServer""" self.check(b, a) def test_name_mutiple_imports_indented(self): b = """ def indented(): import math, http.server, urllib.request, string""" a = """ def indented(): import math, string import urllib2, urllib import CGIHTTPServer, SimpleHTTPServer, BaseHTTPServer""" self.check(b, a) def test_from_single(self): b = "from urllib.request import urlopen" a = "from urllib2 import urlopen" self.check(b, a) b = "from urllib.request import urlopen\n"\ "from urllib.parse import urlencode" a = "from urllib2 import urlopen\n"\ "from urllib import urlencode" self.check(b, a) b = "from tkinter.simpledialog import SimpleDialog" a = "from SimpleDialog import SimpleDialog" self.check(b, a) def test_from_star(self): b = """ def try_import(package): try: from http.server import * print('success') except ImportError: print('failure', end="") print('try again!') """ a = """ def try_import(package): try: from BaseHTTPServer import * from CGIHTTPServer import * from SimpleHTTPServer import * print('success') except ImportError: print('failure', end="") print('try again!') """ self.check(b, a, ignore_warnings=True) b = """ def testing_http_server(): from http.server import * test_all_imports() def testing_xmlrpc_server(): from xmlrpc.server import * test_all_imports() """ a = """ def testing_http_server(): from BaseHTTPServer import * from CGIHTTPServer import * from SimpleHTTPServer import * test_all_imports() def testing_xmlrpc_server(): from SimpleXMLRPCServer import * from DocXMLRPCServer import * test_all_imports() """ self.check(b, a, ignore_warnings=True) def test_from_list(self): b = """ with open('myFile', 'r') as myFile: from urllib.request import install_opener, urlretrieve, unquote as billybob fileList = [ln for ln in myFile]""" a = """ with open('myFile', 'r') as myFile: from urllib2 import install_opener from urllib import urlretrieve, unquote as billybob fileList = [ln for ln in myFile]""" try: self.check(b, a, ignore_warnings=True) except AssertionError: a = """ with open('myFile', 'r') as myFile: from urllib import urlretrieve, unquote as billybob from urllib2 import install_opener fileList = [ln for ln in myFile]""" self.check(b, a, ignore_warnings=True) if False: def test_modulefrom(self): b = """ if spam.is_good(): from urllib import request, parse request.urlopen(spam_site) parse.urlencode(spam_site)""" a = """ if spam.is_good(): import urllib import urllib2 urllib2.urlopen(spam_site) urllib.urlencode(spam_site)""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_imports.py0000666000000000000000000001713512513010502016525 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_imports(lib3to2FixerTestCase): fixer = "imports" def test_various_unchanged(self): # Enclosed in a string s = "'import queue'" self.unchanged(s) # Never was imported s = "print(queue)" self.unchanged(s) def test_all_nodotted_names_solo(self): b = "import configparser" a = "import ConfigParser" self.check(b, a) b = "from winreg import *" a = "from _winreg import *" self.check(b, a) b = "import copyreg" a = "import copy_reg" self.check(b, a) b = "import queue" a = "import Queue" self.check(b, a) b = "import socketserver" a = "import SocketServer" self.check(b, a) b = "import _markupbase" a = "import markupbase" self.check(b, a) b = "import builtins" a = "import __builtin__" self.check(b, a) def test_nodotted_names_duo(self): b = "import configparser, copyreg" a = "import ConfigParser, copy_reg" self.check(b, a) b = "import _markupbase, queue as bob" a = "import markupbase, Queue as bob" self.check(b, a) b = "import socketserver, builtins" a = "import SocketServer, __builtin__" self.check(b, a) def test_nodotted_names_quad(self): b = "import configparser, winreg, socketserver, _markupbase" a = "import ConfigParser, _winreg, SocketServer, markupbase" self.check(b, a) b = "import queue, math, _markupbase, copyreg" a = "import Queue, math, markupbase, copy_reg" self.check(b, a) def test_all_dotted_names_solo(self): b = "import dbm.bsd as bsd" a = "import dbhash as bsd" self.check(b, a) b = "import dbm.ndbm" a = "import dbm" self.check(b, a) b = "import dbm.dumb" a = "import dumbdbm" self.check(b, a) b = "from dbm import gnu" a = "import gdbm as gnu" self.check(b, a) b = "import html.parser" a = "import HTMLParser" self.check(b, a) b = "import html.entities" a = "import htmlentitydefs" self.check(b, a) b = "from http import client" a = "import httplib as client" self.check(b, a) b = "import http.cookies" a = "import Cookie" self.check(b, a) b = "import http.cookiejar" a = "import cookielib" self.check(b, a) b = "import tkinter.dialog" a = "import Dialog" self.check(b, a) b = "import tkinter._fix" a = "import FixTk" self.check(b, a) b = "import tkinter.scrolledtext" a = "import ScrolledText" self.check(b, a) b = "import tkinter.tix" a = "import Tix" self.check(b, a) b = "import tkinter.constants" a = "import Tkconstants" self.check(b, a) b = "import tkinter.dnd" a = "import Tkdnd" self.check(b, a) b = "import tkinter.__init__" a = "import Tkinter" self.check(b, a) b = "import tkinter" a = "import Tkinter" self.check(b, a) b = "import tkinter.colorchooser" a = "import tkColorChooser" self.check(b, a) b = "import tkinter.commondialog" a = "import tkCommonDialog" self.check(b, a) b = "from tkinter.font import *" a = "from tkFont import *" self.check(b, a) b = "import tkinter.messagebox" a = "import tkMessageBox" self.check(b, a) b = "import tkinter.turtle" a = "import turtle" self.check(b, a) b = "import urllib.robotparser" a = "import robotparser" self.check(b, a) b = "import test.support" a = "import test.test_support" self.check(b, a) b = "from test import support" a = "from test import test_support as support" self.check(b, a) b = "import xmlrpc.client" a = "import xmlrpclib" self.check(b, a) b = "from test import support as spam, not_support as not_spam" a = "from test import test_support as spam, not_support as not_spam" self.check(b, a) def test_dotted_names_duo(self): b = "import tkinter.font, dbm.bsd" a = "import tkFont, dbhash" self.check(b, a) b = "import test.support, http.cookies" a = "import test.test_support, Cookie" self.check(b, a) def test_from_import(self): b = "from test.support import things" a = "from test.test_support import things" self.check(b, a) b = "from builtins import open" a = "from __builtin__ import open" self.check(b, a) b = """from socketserver import (ThreadingUDPServer, DatagramRequestHandler, ThreadingTCPServer, StreamRequestHandler)""" a = """from SocketServer import (ThreadingUDPServer, DatagramRequestHandler, ThreadingTCPServer, StreamRequestHandler)""" self.check(b, a) def test_dotted_names_quad(self): b = "import html.parser as spam, math, tkinter.__init__, dbm.gnu #comment!" a = "import HTMLParser as spam, math, Tkinter, gdbm #comment!" self.check(b, a) b = "import math, tkinter.dnd, dbm.ndbm as one, dbm.ndbm as two, urllib" a = "import math, Tkdnd, dbm as one, dbm as two, urllib" self.check(b, a) def test_usage(self): b = """ import queue as james james.do_stuff()""" a = """ import Queue as james james.do_stuff()""" self.check(b, a) b = """ import queue queue.do_stuff()""" a = """ import Queue Queue.do_stuff()""" self.check(b, a) b = """ import dbm.gnu dbm.gnu.open('generic_file')""" a = """ import gdbm gdbm.open('generic_file')""" self.check(b, a) b = """ import tkinter.dialog, tkinter.colorchooser tkinter = tkinter.dialog(tkinter.colorchooser("Just messing around")) tkinter.test_should_work = True tkinter.dialog.dont.code.like.this = True""" a = """ import Dialog, tkColorChooser tkinter = Dialog(tkColorChooser("Just messing around")) tkinter.test_should_work = True Dialog.dont.code.like.this = True""" self.check(b, a) b = """ open = bob import builtins myOpen = builtins.open""" a = """ open = bob import __builtin__ myOpen = __builtin__.open""" self.check(b, a) def test_bare_usage(self): b = """ import builtins hasattr(builtins, "quit")""" a = """ import __builtin__ hasattr(__builtin__, "quit")""" self.check(b, a) def test_no_attribute(self): b = """ import collections import queue MyTuple = collections.namedtuple('MyTuple', ['queue', 'queue1']) tuple_instance = MyTuple(queue.Queue(), queue.Queue()) tuple_instance.queue.put(1) tuple_instance.queue1.put(1)""" a = """ import collections import Queue MyTuple = collections.namedtuple('MyTuple', ['queue', 'queue1']) tuple_instance = MyTuple(Queue.Queue(), Queue.Queue()) tuple_instance.queue.put(1) tuple_instance.queue1.put(1)""" self.check(b, a)3to2-1.1.1/lib3to2/tests/test_getcwd.py0000666000000000000000000000065012513010502016277 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_getcwd(lib3to2FixerTestCase): fixer = "getcwd" def test_prefix_preservation(self): b = """ls = os.listdir( os.getcwd() )""" a = """ls = os.listdir( os.getcwdu() )""" self.check(b, a) b = """whatdir = os.getcwd ( )""" a = """whatdir = os.getcwdu ( )""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_funcattrs.py0000666000000000000000000000143412513010502017034 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_funcattrs(lib3to2FixerTestCase): fixer = "funcattrs" def test_doc_unchanged(self): b = """whats.up.__doc__""" self.unchanged(b) def test_defaults(self): b = """myFunc.__defaults__""" a = """myFunc.func_defaults""" self.check(b, a) def test_closure(self): b = """fore.__closure__""" a = """fore.func_closure""" self.check(b, a) def test_globals(self): b = """funkFunc.__globals__""" a = """funkFunc.func_globals""" self.check(b, a) def test_dict_unchanged(self): b = """tricky.__dict__""" self.unchanged(b) def test_name_unchanged(self): b = """sayMy.__name__""" self.unchanged(b) 3to2-1.1.1/lib3to2/tests/test_fullargspec.py0000666000000000000000000000124412513010502017331 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_fullargspec(lib3to2FixerTestCase): fixer = "fullargspec" def test_import(self): b = "from inspect import blah, blah, getfullargspec, blah, blah" a = "from inspect import blah, blah, getargspec, blah, blah" self.warns(b, a, "some of the values returned by getfullargspec are not valid in Python 2 and have no equivalent.") def test_usage(self): b = "argspec = inspect.getfullargspec(func)" a = "argspec = inspect.getargspec(func)" self.warns(b, a, "some of the values returned by getfullargspec are not valid in Python 2 and have no equivalent.") 3to2-1.1.1/lib3to2/tests/test_except.py0000666000000000000000000000131312513010502016307 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_except(lib3to2FixerTestCase): fixer = "except" def test_prefix_preservation(self): a = """ try: pass except (RuntimeError, ImportError), e: pass""" b = """ try: pass except (RuntimeError, ImportError) as e: pass""" self.check(b, a) def test_simple(self): a = """ try: pass except Foo, e: pass""" b = """ try: pass except Foo as e: pass""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_division.py0000666000000000000000000000110212513010502016637 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase from itertools import count class Test_division(lib3to2FixerTestCase): fixer = "division" counter = count(1) divisions = [("1", "2"), ("spam","eggs"), ("lambda a: a(4)", "my_foot(your_face)"), ("temp(bob)", "4"), ("29.4", "green()")] for top,bottom in divisions: exec("def test_%d(self):\n b = \"%s/%s\"\n a = \"from __future__ import division\\n%s/%s\"\n self.check(b, a)" % (next(counter), top, bottom, top, bottom)) 3to2-1.1.1/lib3to2/tests/test_dctsetcomp.py0000666000000000000000000000356312513010502017175 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_dctsetcomp(lib3to2FixerTestCase): fixer = "dctsetcomp" def test_dictcomp_straightforward(self): b = "{key:val for (key, val) in tuple_of_stuff}" a = "dict((key, val) for (key, val) in tuple_of_stuff)" self.check(b, a) def test_dictcomp_nestedstuff_noif(self): b = "{hashlify(spam):valuate(ham).whatsthis(eggs) for \ (spam, ham, eggs) in spam_iterator}" a = "dict((hashlify(spam), valuate(ham).whatsthis(eggs)) for \ (spam, ham, eggs) in spam_iterator)" self.check(b, a) def test_dictcomp_nestedstuff_withif(self): b = "{moo:(lambda new: None)(cow) for (moo, cow) in \ farm_animal['cow'] if has_milk()}" a = "dict((moo, (lambda new: None)(cow)) for (moo, cow) in \ farm_animal['cow'] if has_milk())" self.check(b, a) def test_setcomps(self): """ setcomp fixer should keep everything inside the same and only replace the {} with a set() call on a gencomp """ tests = [] tests.append("milk.price for milk in find_milk(store)") tests.append("compute_nth_prime(generate_complicated_thing(\ n.value(hashlifier))) for n in my_range_func(1, (how_far+offset))") tests.append("compute_nth_prime(generate_complicated_thing(\ n.value(hashlifier))) for n in my_range_func(1, (how_far+offset))\ if a==b.spam()") for comp in tests: b = "{%s}" % comp a = "set(%s)" % comp self.check(b, a) def test_prefixes(self): b = "spam = {foo for foo in bar}" a = "spam = set(foo for foo in bar)" self.check(b, a) b = "spam = {foo:bar for (foo, bar) in baz}" a = "spam = dict((foo, bar) for (foo, bar) in baz)" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_collections.py0000666000000000000000000000251312513010502017340 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_collections(lib3to2FixerTestCase): fixer = "collections" def test_from_UserDict(self): b = """ from collections import UserDict""" a = """ from UserDict import UserDict""" self.check(b, a) def test_from_UserList(self): b = """ from collections import UserList""" a = """ from UserList import UserList""" self.check(b, a) def test_from_UserString(self): b = """ from collections import UserString""" a = """ from UserString import UserString""" self.check(b, a) def test_using_UserDict(self): b = """ class Scapegoat(collections.UserDict): pass""" a = """import UserDict class Scapegoat(UserDict.UserDict): pass""" self.check(b, a) def test_using_UserList(self): b = """ class Scapegoat(collections.UserList): pass""" a = """import UserList class Scapegoat(UserList.UserList): pass""" self.check(b, a) def test_using_UserString(self): b = """ class Scapegoat(collections.UserString): pass""" a = """import UserString class Scapegoat(UserString.UserString): pass""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_classdecorator.py0000666000000000000000000000364412513010502020040 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_classdecorator(lib3to2FixerTestCase): fixer = "classdecorator" def test_basic_functionality(self): b = """ @decor class decorated(object): pass""" a = """ class decorated(object): pass decorated = decor(decorated)""" self.check(b, a) def test_whitespace(self): b = """ @decor class decorated(object): pass print("hello, there!")""" a = """ class decorated(object): pass decorated = decor(decorated) print("hello, there!")""" self.check(b, a) def test_chained(self): b = """ @f1 @f2 @f3 class wow(object): do_cool_stuff_here()""" a = """ class wow(object): do_cool_stuff_here() wow = f1(f2(f3(wow)))""" self.check(b, a) def test_dots_and_parens(self): b = """ @should_work.with_dots(and_parens) @dotted.name @with_args(in_parens) class awesome(object): inconsequential_stuff()""" a = """ class awesome(object): inconsequential_stuff() awesome = should_work.with_dots(and_parens)(dotted.name(with_args(in_parens)(awesome)))""" self.check(b, a) def test_indentation(self): b = """ if 1: if 2: if 3: @something @something_else class foo(bar): do_stuff() elif 4: pass""" a = """ if 1: if 2: if 3: class foo(bar): do_stuff() foo = something(something_else(foo)) elif 4: pass""" 3to2-1.1.1/lib3to2/tests/test_bytes.py0000666000000000000000000000244112513010502016150 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_bytes(lib3to2FixerTestCase): fixer = "bytes" def test_bytes_call_1(self): b = """bytes(x)""" a = """str(x)""" self.check(b, a) def test_bytes_call_2(self): b = """a = bytes(x) + b"florist" """ a = """a = str(x) + "florist" """ self.check(b, a) def test_bytes_call_noargs(self): b = """bytes()""" a = """str()""" self.check(b, a) def test_bytes_call_args_1(self): b = """bytes(x, y, z)""" a = """str(x).encode(y, z)""" self.check(b, a) def test_bytes_call_args_2(self): b = """bytes(encoding="utf-8", source="dinosaur", errors="dont-care")""" a = """str("dinosaur").encode("utf-8", "dont-care")""" self.check(b, a) def test_bytes_literal_1(self): b = '''b"\x41"''' a = '''"\x41"''' self.check(b, a) def test_bytes_literal_2(self): b = """b'x'""" a = """'x'""" self.check(b, a) def test_bytes_literal_3(self): b = """BR'''\x13'''""" a = """R'''\x13'''""" self.check(b, a) def test_bytes_concatenation(self): b = """b'bytes' + b'bytes'""" a = """'bytes' + 'bytes'""" self.check(b, a) 3to2-1.1.1/lib3to2/tests/test_bool.py0000666000000000000000000000226512513010502015761 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_bool(lib3to2FixerTestCase): fixer = "bool" def test_1(self): b = """ class A: def __bool__(self): pass """ a = """ class A: def __nonzero__(self): pass """ self.check(b, a) def test_2(self): b = """ class A(object): def __bool__(self): pass """ a = """ class A(object): def __nonzero__(self): pass """ self.check(b, a) def test_unchanged_1(self): s = """ class A(object): def __nonzero__(self): pass """ self.unchanged(s) def test_unchanged_2(self): s = """ class A(object): def __bool__(self, a): pass """ self.unchanged(s) def test_unchanged_func(self): s = """ def __bool__(thing): pass """ self.unchanged(s) 3to2-1.1.1/lib3to2/tests/test_bitlength.py0000666000000000000000000000071312513010502017002 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_bitlength(lib3to2FixerTestCase): fixer = 'bitlength' def test_fixed(self): b = """a = something.bit_length()""" a = """a = (len(bin(something)) - 2)""" self.check(b, a, ignore_warnings=True) def test_unfixed(self): s = """a = bit_length(fire)""" self.unchanged(s) s = """a = s.bit_length('some_arg')""" self.unchanged(s) 3to2-1.1.1/lib3to2/tests/test_annotations.py0000666000000000000000000000543312513010502017363 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_annotations(lib3to2FixerTestCase): fixer = "annotations" def test_return_annotations_alone(self): b = "def foo() -> 'bar': pass" a = "def foo(): pass" self.check(b, a, ignore_warnings=True) b = """ def foo() -> "bar": print "baz" print "what's next, again?" """ a = """ def foo(): print "baz" print "what's next, again?" """ self.check(b, a, ignore_warnings=True) def test_single_param_annotations(self): b = "def foo(bar:'baz'): pass" a = "def foo(bar): pass" self.check(b, a, ignore_warnings=True) b = """ def foo(bar:"baz"="spam"): print "what's next, again?" print "whatever." """ a = """ def foo(bar="spam"): print "what's next, again?" print "whatever." """ self.check(b, a, ignore_warnings=True) def test_multiple_param_annotations(self): b = "def foo(bar:'spam'=False, baz:'eggs'=True, ham:False='spaghetti'): pass" a = "def foo(bar=False, baz=True, ham='spaghetti'): pass" self.check(b, a, ignore_warnings=True) b = """ def foo(bar:"spam"=False, baz:"eggs"=True, ham:False="spam"): print "this is filler, just doing a suite" print "suites require multiple lines." """ a = """ def foo(bar=False, baz=True, ham="spam"): print "this is filler, just doing a suite" print "suites require multiple lines." """ self.check(b, a, ignore_warnings=True) def test_mixed_annotations(self): b = "def foo(bar=False, baz:'eggs'=True, ham:False='spaghetti') -> 'zombies': pass" a = "def foo(bar=False, baz=True, ham='spaghetti'): pass" self.check(b, a, ignore_warnings=True) b = """ def foo(bar:"spam"=False, baz=True, ham:False="spam") -> 'air': print "this is filler, just doing a suite" print "suites require multiple lines." """ a = """ def foo(bar=False, baz=True, ham="spam"): print "this is filler, just doing a suite" print "suites require multiple lines." """ self.check(b, a, ignore_warnings=True) b = "def foo(bar) -> 'brains': pass" a = "def foo(bar): pass" self.check(b, a, ignore_warnings=True) def test_unchanged(self): s = "def foo(): pass" self.unchanged(s) s = """ def foo(): pass pass """ self.unchanged(s) s = """ def foo(bar=baz): pass pass """ self.unchanged(s) 3to2-1.1.1/lib3to2/tests/test_absimport.py0000666000000000000000000000054412513010502017024 0ustar rootrootfrom lib3to2.tests.support import lib3to2FixerTestCase class Test_absimport(lib3to2FixerTestCase): fixer = 'absimport' def test_import(self): a = 'import abc' b = 'from __future__ import absolute_import\nimport abc' self.check(a, b) def test_no_imports(self): a = '2+2' self.unchanged(a) 3to2-1.1.1/lib3to2/tests/support.py0000666000000000000000000000727512513010502015511 0ustar rootroot"""Support code for test_*.py files""" import unittest from itertools import chain from lib2to3 import pygram from lib2to3 import refactor from textwrap import dedent def run_all_tests(test_mod=None, tests=None): # From lib2to3.tests.support (copied without changes). if tests is None: tests = unittest.TestLoader().loadTestsFromModule(test_mod) return unittest.TextTestRunner(verbosity=2).run(tests) def reformat(string): # From lib2to3.tests.support (copied without changes). return dedent(string) + "\n\n" def get_refactorer(fixer_pkg="lib2to3", fixers=None, options=None): # From lib2to3.tests.support (copied without changes). """ A convenience function for creating a RefactoringTool for tests. fixers is a list of fixers for the RefactoringTool to use. By default "lib2to3.fixes.*" is used. options is an optional dictionary of options to be passed to the RefactoringTool. """ if fixers is not None: fixers = [fixer_pkg + ".fixes.fix_" + fix for fix in fixers] else: fixers = refactor.get_fixers_from_package(fixer_pkg + ".fixes") options = options or {} return refactor.RefactoringTool(fixers, options, explicit=True) class FixerTestCase(unittest.TestCase): # From lib2to3.tests.support (adapted with very minor changes). # Other test cases can subclass this class and replace "fixer_pkg" with # their own. def setUp(self, fix_list=None, fixer_pkg="lib2to3", options=None): if fix_list is None: fix_list = [self.fixer] self.refactor = get_refactorer(fixer_pkg, fix_list, options) self.fixer_log = [] self.filename = "" for fixer in chain(self.refactor.pre_order, self.refactor.post_order): fixer.log = self.fixer_log def _check(self, before, after): before = reformat(before) after = reformat(after) tree = self.refactor.refactor_string(before, self.filename) self.assertEqual(after, str(tree)) return tree def check(self, before, after, ignore_warnings=False): tree = self._check(before, after) self.assertTrue(tree.was_changed) if not ignore_warnings: self.assertEqual(self.fixer_log, []) def warns(self, before, after, message, unchanged=False): tree = self._check(before, after) self.assertTrue(message in "".join(self.fixer_log)) if not unchanged: self.assertTrue(tree.was_changed) def warns_unchanged(self, before, message): self.warns(before, before, message, unchanged=True) def unchanged(self, before, ignore_warnings=False): self._check(before, before) if not ignore_warnings: self.assertEqual(self.fixer_log, []) def assert_runs_after(self, *names): fixes = [self.fixer] fixes.extend(names) r = get_refactorer("lib2to3", fixes) (pre, post) = r.get_fixers() n = "fix_" + self.fixer if post and post[-1].__class__.__module__.endswith(n): # We're the last fixer to run return if pre and pre[-1].__class__.__module__.endswith(n) and not post: # We're the last in pre and post is empty return self.fail("Fixer run order (%s) is incorrect; %s should be last."\ %(", ".join([x.__class__.__module__ for x in (pre+post)]), n)) class lib3to2FixerTestCase(FixerTestCase): # From lib3to2.tests.test_all_fixers (moved without changes). def setUp(self, fix_list=None, fixer_pkg="lib3to2"): super(lib3to2FixerTestCase, self).setUp(fixer_pkg=fixer_pkg) self.refactor.driver.grammar = pygram.python_grammar_no_print_statement 3to2-1.1.1/lib3to2/fixes/0000775000000000000000000000000012555622334013404 5ustar rootroot3to2-1.1.1/lib3to2/fixes/__init__.py0000666000000000000000000000000712513000130015466 0ustar rootroot#empty 3to2-1.1.1/lib3to2/fixes/imports_fix_alt_formatting.py0000666000000000000000000002540212513010502021376 0ustar rootroot""" Fixer for standard library imports renamed in Python 3 """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name, is_probably_builtin, Newline, does_tree_import from lib2to3.pygram import python_symbols as syms from lib2to3.pgen2 import token from lib2to3.pytree import Node, Leaf from ..fixer_util import NameImport # used in simple_mapping_to_pattern() MAPPING = {"reprlib": "repr", "winreg": "_winreg", "configparser": "ConfigParser", "copyreg": "copy_reg", "queue": "Queue", "socketserver": "SocketServer", "_markupbase": "markupbase", "test.support": "test.test_support", "dbm.bsd": "dbhash", "dbm.ndbm": "dbm", "dbm.dumb": "dumbdbm", "dbm.gnu": "gdbm", "html.parser": "HTMLParser", "html.entities": "htmlentitydefs", "http.client": "httplib", "http.cookies": "Cookie", "http.cookiejar": "cookielib", "tkinter": "Tkinter", "tkinter.dialog": "Dialog", "tkinter._fix": "FixTk", "tkinter.scrolledtext": "ScrolledText", "tkinter.tix": "Tix", "tkinter.constants": "Tkconstants", "tkinter.dnd": "Tkdnd", "tkinter.__init__": "Tkinter", "tkinter.colorchooser": "tkColorChooser", "tkinter.commondialog": "tkCommonDialog", "tkinter.font": "tkFont", "tkinter.messagebox": "tkMessageBox", "tkinter.turtle": "turtle", "urllib.robotparser": "robotparser", "xmlrpc.client": "xmlrpclib", "builtins": "__builtin__", } # generic strings to help build patterns # these variables mean (with http.client.HTTPConnection as an example): # name = http # attr = client # used = HTTPConnection # fmt_name is a formatted subpattern (simple_name_match or dotted_name_match) # helps match 'queue', as in 'from queue import ...' simple_name_match = "name='%s'" # helps match 'client', to be used if client has been imported from http subname_match = "attr='%s'" # helps match 'http.client', as in 'import urllib.request' dotted_name_match = "dotted_name=dotted_name< %s '.' %s >" # helps match 'queue', as in 'queue.Queue(...)' power_onename_match = "%s" # helps match 'http.client', as in 'http.client.HTTPConnection(...)' power_twoname_match = "power< %s trailer< '.' %s > any* >" # helps match 'client.HTTPConnection', if 'client' has been imported from http power_subname_match = "power< %s any* >" # helps match 'from http.client import HTTPConnection' from_import_match = "from_import=import_from< 'from' %s 'import' imported=any >" # helps match 'from http import client' from_import_submod_match = "from_import_submod=import_from< 'from' %s 'import' (%s | import_as_name< %s 'as' renamed=any > | import_as_names< any* (%s | import_as_name< %s 'as' renamed=any >) any* > ) >" # helps match 'import urllib.request' name_import_match = "name_import=import_name< 'import' %s > | name_import=import_name< 'import' dotted_as_name< %s 'as' renamed=any > >" # helps match 'import http.client, winreg' multiple_name_import_match = "name_import=import_name< 'import' dotted_as_names< names=any* > >" def all_patterns(name): """ Accepts a string and returns a pattern of possible patterns involving that name Called by simple_mapping_to_pattern for each name in the mapping it receives. """ # i_ denotes an import-like node # u_ denotes a node that appears to be a usage of the name if '.' in name: name, attr = name.split('.', 1) simple_name = simple_name_match % (name) simple_attr = subname_match % (attr) dotted_name = dotted_name_match % (simple_name, simple_attr) i_from = from_import_match % (dotted_name) i_from_submod = from_import_submod_match % (simple_name, simple_attr, simple_attr, simple_attr, simple_attr) i_name = name_import_match % (dotted_name, dotted_name) u_name = power_twoname_match % (simple_name, simple_attr) u_subname = power_subname_match % (simple_attr) return ' | \n'.join((i_name, i_from, i_from_submod, u_name, u_subname)) else: simple_name = simple_name_match % (name) i_name = name_import_match % (simple_name, simple_name) i_from = from_import_match % (simple_name) u_name = power_onename_match % (simple_name) return ' | \n'.join((i_name, i_from, u_name)) class FixImports(fixer_base.BaseFix): order = "pre" PATTERN = ' | \n'.join([all_patterns(name) for name in MAPPING]) PATTERN = ' | \n'.join((PATTERN, multiple_name_import_match)) def fix_dotted_name(self, node, mapping=MAPPING): """ Accepts either a DottedName node or a power node with a trailer. If mapping is given, use it; otherwise use our MAPPING Returns a node that can be in-place replaced by the node given """ if node.type == syms.dotted_name: _name = node.children[0] _attr = node.children[2] elif node.type == syms.power: _name = node.children[0] _attr = node.children[1].children[1] name = _name.value attr = _attr.value full_name = name + '.' + attr if not full_name in mapping: return to_repl = mapping[full_name] if '.' in to_repl: repl_name, repl_attr = to_repl.split('.') _name.replace(Name(repl_name, prefix=_name.prefix)) _attr.replace(Name(repl_attr, prefix=_attr.prefix)) elif node.type == syms.dotted_name: node.replace(Name(to_repl, prefix=node.prefix)) elif node.type == syms.power: _name.replace(Name(to_repl, prefix=_name.prefix)) parent = _attr.parent _attr.remove() parent.remove() def fix_simple_name(self, node, mapping=MAPPING): """ Accepts a Name leaf. If mapping is given, use it; otherwise use our MAPPING Returns a node that can be in-place replaced by the node given """ assert node.type == token.NAME, repr(node) if not node.value in mapping: return replacement = mapping[node.value] node.replace(Leaf(token.NAME, str(replacement), prefix=node.prefix)) def fix_submod_import(self, imported, name, node): """ Accepts a list of NAME leafs, a name string, and a node node is given as an argument to BaseFix.transform() NAME leafs come from an import_as_names node (the children) name string is the base name found in node. """ submods = [] missed = [] for attr in imported: dotted = '.'.join((name, attr.value)) if dotted in MAPPING: # get the replacement module to_repl = MAPPING[dotted] if '.' not in to_repl: # it's a simple name, so use a simple replacement. _import = NameImport(Name(to_repl, prefix=" "), attr.value) submods.append(_import) elif attr.type == token.NAME: missed.append(attr.clone()) if not submods: return parent = node.parent node.replace(submods[0]) if len(submods) > 1: start = submods.pop(0) prev = start for submod in submods: parent.append_child(submod) if missed: self.warning(node, "Imported names not known to 3to2 to be part of the package %s. Leaving those alone... high probability that this code will be incorrect." % (name)) children = [Name("from"), Name(name, prefix=" "), Name("import", prefix=" "), Node(syms.import_as_names, missed)] orig_stripped = Node(syms.import_from, children) parent.append_child(Newline()) parent.append_child(orig_stripped) def get_dotted_import_replacement(self, name_node, attr_node, mapping=MAPPING, renamed=None): """ For (http, client) given and httplib being the correct replacement, returns (httplib as client, None) For (test, support) given and test.test_support being the replacement, returns (test, test_support as support) """ full_name = name_node.value + '.' + attr_node.value replacement = mapping[full_name] if '.' in replacement: new_name, new_attr = replacement.split('.') if renamed is None: return Name(new_name, prefix=name_node.prefix), Node(syms.dotted_as_name, [Name(new_attr, prefix=attr_node.prefix), Name('as', prefix=" "), attr_node.clone()]) else: return Name(new_name, prefix=name_node.prefix), Name(new_attr, prefix=attr_node.prefix) else: return Node(syms.dotted_as_name, [Name(replacement, prefix=name_node.prefix), Name('as', prefix=' '), Name(attr_node.value, prefix=attr_node.prefix)]), None def transform(self, node, results): from_import = results.get("from_import") from_import_submod = results.get("from_import_submod") name_import = results.get("name_import") dotted_name = results.get("dotted_name") name = results.get("name") names = results.get("names") attr = results.get("attr") imported = results.get("imported") if names: for name in names: if name.type == token.NAME: self.fix_simple_name(name) elif name.type == syms.dotted_as_name: self.fix_simple_name(name.children[0]) if name.children[0].type == token.NAME else \ self.fix_dotted_name(name.children[0]) elif name.type == syms.dotted_name: self.fix_dotted_name(name) elif from_import_submod: renamed = results.get("renamed") new_name, new_attr = self.get_dotted_import_replacement(name, attr, renamed=renamed) if new_attr is not None: name.replace(new_name) attr.replace(new_attr) else: children = [Name("import"), new_name] node.replace(Node(syms.import_name, children, prefix=node.prefix)) elif dotted_name: self.fix_dotted_name(dotted_name) elif name_import or from_import: self.fix_simple_name(name) elif name and not attr: if does_tree_import(None, MAPPING[name.value], node): self.fix_simple_name(name) elif name and attr: # Note that this will fix a dotted name that was never imported. This will probably not matter. self.fix_dotted_name(node) elif imported and imported.type == syms.import_as_names: self.fix_submod_import(imported=imported.children, node=node, name=name.value) 3to2-1.1.1/lib3to2/fixes/imports2_fix_alt_formatting.py0000666000000000000000000003737712513010502021476 0ustar rootroot""" Fixer for complicated imports """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name, String, FromImport, Newline, Comma from ..fixer_util import token, syms, Leaf, Node, Star, indentation, ImportAsName TK_BASE_NAMES = ('ACTIVE', 'ALL', 'ANCHOR', 'ARC','BASELINE', 'BEVEL', 'BOTH', 'BOTTOM', 'BROWSE', 'BUTT', 'CASCADE', 'CENTER', 'CHAR', 'CHECKBUTTON', 'CHORD', 'COMMAND', 'CURRENT', 'DISABLED', 'DOTBOX', 'E', 'END', 'EW', 'EXCEPTION', 'EXTENDED', 'FALSE', 'FIRST', 'FLAT', 'GROOVE', 'HIDDEN', 'HORIZONTAL', 'INSERT', 'INSIDE', 'LAST', 'LEFT', 'MITER', 'MOVETO', 'MULTIPLE', 'N', 'NE', 'NO', 'NONE', 'NORMAL', 'NS', 'NSEW', 'NUMERIC', 'NW', 'OFF', 'ON', 'OUTSIDE', 'PAGES', 'PIESLICE', 'PROJECTING', 'RADIOBUTTON', 'RAISED', 'READABLE', 'RIDGE', 'RIGHT', 'ROUND', 'S', 'SCROLL', 'SE', 'SEL', 'SEL_FIRST', 'SEL_LAST', 'SEPARATOR', 'SINGLE', 'SOLID', 'SUNKEN', 'SW', 'StringTypes', 'TOP', 'TRUE', 'TclVersion', 'TkVersion', 'UNDERLINE', 'UNITS', 'VERTICAL', 'W', 'WORD', 'WRITABLE', 'X', 'Y', 'YES', 'wantobjects') PY2MODULES = { 'urllib2' : ( 'AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'AbstractHTTPHandler', 'BaseHandler', 'CacheFTPHandler', 'FTPHandler', 'FileHandler', 'HTTPBasicAuthHandler', 'HTTPCookieProcessor', 'HTTPDefaultErrorHandler', 'HTTPDigestAuthHandler', 'HTTPError', 'HTTPErrorProcessor', 'HTTPHandler', 'HTTPPasswordMgr', 'HTTPPasswordMgrWithDefaultRealm', 'HTTPRedirectHandler', 'HTTPSHandler', 'OpenerDirector', 'ProxyBasicAuthHandler', 'ProxyDigestAuthHandler', 'ProxyHandler', 'Request', 'StringIO', 'URLError', 'UnknownHandler', 'addinfourl', 'build_opener', 'install_opener', 'parse_http_list', 'parse_keqv_list', 'randombytes', 'request_host', 'urlopen'), 'urllib' : ( 'ContentTooShortError', 'FancyURLopener','URLopener', 'basejoin', 'ftperrors', 'getproxies', 'getproxies_environment', 'localhost', 'pathname2url', 'quote', 'quote_plus', 'splitattr', 'splithost', 'splitnport', 'splitpasswd', 'splitport', 'splitquery', 'splittag', 'splittype', 'splituser', 'splitvalue', 'thishost', 'unquote', 'unquote_plus', 'unwrap', 'url2pathname', 'urlcleanup', 'urlencode', 'urlopen', 'urlretrieve',), 'urlparse' : ( 'parse_qs', 'parse_qsl', 'urldefrag', 'urljoin', 'urlparse', 'urlsplit', 'urlunparse', 'urlunsplit'), 'dbm' : ( 'ndbm', 'gnu', 'dumb'), 'anydbm' : ( 'error', 'open'), 'whichdb' : ( 'whichdb',), 'BaseHTTPServer' : ( 'BaseHTTPRequestHandler', 'HTTPServer'), 'CGIHTTPServer' : ( 'CGIHTTPRequestHandler',), 'SimpleHTTPServer' : ( 'SimpleHTTPRequestHandler',), 'FileDialog' : TK_BASE_NAMES + ( 'FileDialog', 'LoadFileDialog', 'SaveFileDialog', 'dialogstates', 'test'), 'tkFileDialog' : ( 'Directory', 'Open', 'SaveAs', '_Dialog', 'askdirectory', 'askopenfile', 'askopenfilename', 'askopenfilenames', 'askopenfiles', 'asksaveasfile', 'asksaveasfilename'), 'SimpleDialog' : TK_BASE_NAMES + ( 'SimpleDialog',), 'tkSimpleDialog' : TK_BASE_NAMES + ( 'askfloat', 'askinteger', 'askstring', 'Dialog'), 'SimpleXMLRPCServer' : ( 'CGIXMLRPCRequestHandler', 'SimpleXMLRPCDispatcher', 'SimpleXMLRPCRequestHandler', 'SimpleXMLRPCServer', 'list_public_methods', 'remove_duplicates', 'resolve_dotted_attribute'), 'DocXMLRPCServer' : ( 'DocCGIXMLRPCRequestHandler', 'DocXMLRPCRequestHandler', 'DocXMLRPCServer', 'ServerHTMLDoc','XMLRPCDocGenerator'), } MAPPING = { 'urllib.request' : ('urllib2', 'urllib'), 'urllib.error' : ('urllib2', 'urllib'), 'urllib.parse' : ('urllib2', 'urllib', 'urlparse'), 'dbm.__init__' : ('anydbm', 'whichdb'), 'http.server' : ('CGIHTTPServer', 'SimpleHTTPServer', 'BaseHTTPServer'), 'tkinter.filedialog' : ('tkFileDialog', 'FileDialog'), 'tkinter.simpledialog' : ('tkSimpleDialog', 'SimpleDialog'), 'xmlrpc.server' : ('DocXMLRPCServer', 'SimpleXMLRPCServer'), } # helps match 'http', as in 'from http.server import ...' simple_name = "name='%s'" # helps match 'server', as in 'from http.server import ...' simple_attr = "attr='%s'" # helps match 'HTTPServer', as in 'from http.server import HTTPServer' simple_using = "using='%s'" # helps match 'urllib.request', as in 'import urllib.request' dotted_name = "dotted_name=dotted_name< %s '.' %s >" # helps match 'http.server', as in 'http.server.HTTPServer(...)' power_twoname = "pow=power< %s trailer< '.' %s > trailer< '.' using=any > any* >" # helps match 'dbm.whichdb', as in 'dbm.whichdb(...)' power_onename = "pow=power< %s trailer< '.' using=any > any* >" # helps match 'from http.server import HTTPServer' # also helps match 'from http.server import HTTPServer, SimpleHTTPRequestHandler' # also helps match 'from http.server import *' from_import = "from_import=import_from< 'from' %s 'import' (import_as_name< using=any 'as' renamed=any> | in_list=import_as_names< using=any* > | using='*' | using=NAME) >" # helps match 'import urllib.request' name_import = "name_import=import_name< 'import' (%s | in_list=dotted_as_names< imp_list=any* >) >" ############# # WON'T FIX # ############# # helps match 'import urllib.request as name' name_import_rename = "name_import_rename=dotted_as_name< %s 'as' renamed=any >" # helps match 'from http import server' from_import_rename = "from_import_rename=import_from< 'from' %s 'import' (%s | import_as_name< %s 'as' renamed=any > | in_list=import_as_names< any* (%s | import_as_name< %s 'as' renamed=any >) any* >) >" def all_modules_subpattern(): """ Builds a pattern for all toplevel names (urllib, http, etc) """ names_dot_attrs = [mod.split(".") for mod in MAPPING] ret = "( " + " | ".join([dotted_name % (simple_name % (mod[0]), simple_attr % (mod[1])) for mod in names_dot_attrs]) ret += " | " ret += " | ".join([simple_name % (mod[0]) for mod in names_dot_attrs if mod[1] == "__init__"]) + " )" return ret def all_candidates(name, attr, MAPPING=MAPPING): """ Returns all candidate packages for the name.attr """ dotted = name + '.' + attr assert dotted in MAPPING, "No matching package found." ret = MAPPING[dotted] if attr == '__init__': return ret + (name,) return ret def new_package(name, attr, using, MAPPING=MAPPING, PY2MODULES=PY2MODULES): """ Returns which candidate package for name.attr provides using """ for candidate in all_candidates(name, attr, MAPPING): if using in PY2MODULES[candidate]: break else: candidate = None return candidate def build_import_pattern(mapping1, mapping2): """ mapping1: A dict mapping py3k modules to all possible py2k replacements mapping2: A dict mapping py2k modules to the things they do This builds a HUGE pattern to match all ways that things can be imported """ # py3k: urllib.request, py2k: ('urllib2', 'urllib') yield from_import % (all_modules_subpattern()) for py3k, py2k in mapping1.items(): name, attr = py3k.split('.') s_name = simple_name % (name) s_attr = simple_attr % (attr) d_name = dotted_name % (s_name, s_attr) yield name_import % (d_name) yield power_twoname % (s_name, s_attr) if attr == '__init__': yield name_import % (s_name) yield power_onename % (s_name) yield name_import_rename % (d_name) yield from_import_rename % (s_name, s_attr, s_attr, s_attr, s_attr) def name_import_replacement(name, attr): children = [Name("import")] for c in all_candidates(name.value, attr.value): children.append(Name(c, prefix=" ")) children.append(Comma()) children.pop() replacement = Node(syms.import_name, children) return replacement class FixImports2(fixer_base.BaseFix): run_order = 4 PATTERN = " | \n".join(build_import_pattern(MAPPING, PY2MODULES)) def transform(self, node, results): # The patterns dictate which of these names will be defined name = results.get("name") attr = results.get("attr") if attr is None: attr = Name("__init__") using = results.get("using") in_list = results.get("in_list") imp_list = results.get("imp_list") power = results.get("pow") before = results.get("before") after = results.get("after") d_name = results.get("dotted_name") # An import_stmt is always contained within a simple_stmt simple_stmt = node.parent # The parent is useful for adding new import_stmts parent = simple_stmt.parent idx = parent.children.index(simple_stmt) if any((results.get("from_import_rename") is not None, results.get("name_import_rename") is not None)): self.cannot_convert(node, reason="ambiguity: import binds a single name") elif using is None and not in_list: # import urllib.request, single-name import replacement = name_import_replacement(name, attr) replacement.prefix = node.prefix node.replace(replacement) elif using is None: # import ..., urllib.request, math, http.sever, ... for d_name in imp_list: if d_name.type == syms.dotted_name: name = d_name.children[0] attr = d_name.children[2] elif d_name.type == token.NAME and d_name.value + ".__init__" in MAPPING: name = d_name attr = Name("__init__") else: continue if name.value + "." + attr.value not in MAPPING: continue candidates = all_candidates(name.value, attr.value) children = [Name("import")] for c in candidates: children.append(Name(c, prefix=" ")) children.append(Comma()) children.pop() # Put in the new statement. indent = indentation(simple_stmt) next_stmt = Node(syms.simple_stmt, [Node(syms.import_name, children), Newline()]) parent.insert_child(idx+1, next_stmt) parent.insert_child(idx+1, Leaf(token.INDENT, indent)) # Remove the old imported name test_comma = d_name.next_sibling if test_comma and test_comma.type == token.COMMA: test_comma.remove() elif test_comma is None: test_comma = d_name.prev_sibling if test_comma and test_comma.type == token.COMMA: test_comma.remove() d_name.remove() if not in_list.children: simple_stmt.remove() elif in_list is not None: ########################################################## # "from urllib.request import urlopen, urlretrieve, ..." # # Replace one import statement with potentially many. # ########################################################## packages = dict([(n,[]) for n in all_candidates(name.value, attr.value)]) # Figure out what names need to be imported from what # Add them to a dict to be parsed once we're completely done for imported in using: if imported.type == token.COMMA: continue if imported.type == syms.import_as_name: test_name = imported.children[0].value if len(imported.children) > 2: # 'as' whatever rename = imported.children[2].value else: rename = None elif imported.type == token.NAME: test_name = imported.value rename = None pkg = new_package(name.value, attr.value, test_name) packages[pkg].append((test_name, rename)) # Parse the dict to create new import statements to replace this one imports = [] for new_pkg, names in packages.items(): if not names: # Didn't import anything from that package, move along continue new_names = [] for test_name, rename in names: if rename is None: new_names.append(Name(test_name, prefix=" ")) else: new_names.append(ImportAsName(test_name, rename, prefix=" ")) new_names.append(Comma()) new_names.pop() imports.append(FromImport(new_pkg, new_names)) # Replace this import statement with one of the others replacement = imports.pop() replacement.prefix = node.prefix node.replace(replacement) indent = indentation(simple_stmt) # Add the remainder of the imports as new statements. while imports: next_stmt = Node(syms.simple_stmt, [imports.pop(), Newline()]) parent.insert_child(idx+1, next_stmt) parent.insert_child(idx+1, Leaf(token.INDENT, indent)) elif using.type == token.STAR: # from urllib.request import * nodes = [FromImport(pkg, [Star(prefix=" ")]) for pkg in all_candidates(name.value, attr.value)] replacement = nodes.pop() replacement.prefix = node.prefix node.replace(replacement) indent = indentation(simple_stmt) while nodes: next_stmt = Node(syms.simple_stmt, [nodes.pop(), Newline()]) parent.insert_child(idx+1, next_stmt) parent.insert_child(idx+1, Leaf(token.INDENT, indent)) elif power is not None: # urllib.request.urlopen # Replace it with urllib2.urlopen pkg = new_package(name.value, attr.value, using.value) # Remove the trailer node that contains attr. if attr.parent: attr.parent.remove() name.replace(Name(pkg, prefix=name.prefix)) elif using.type == token.NAME: # from urllib.request import urlopen pkg = new_package(name.value, attr.value, using.value) if attr.value == "__init__" and pkg == name.value: # Replacing "from abc import xyz" with "from abc import xyz" # Just leave it alone so as not to mess with other fixers return else: node.replace(FromImport(pkg, [using])) 3to2-1.1.1/lib3to2/fixes/fix_with.py0000666000000000000000000000042512513010502015560 0ustar rootroot""" Fixer for from __future__ import with_statement """ from lib2to3 import fixer_base from ..fixer_util import future_import class FixWith(fixer_base.BaseFix): PATTERN = "with_stmt" def transform(self, node, results): future_import("with_statement", node) 3to2-1.1.1/lib3to2/fixes/fix_unpacking.py0000666000000000000000000001306712513010502016572 0ustar rootroot""" Fixer for: (a,)* *b (,c)* [,] = s for (a,)* *b (,c)* [,] in d: ... """ from lib2to3 import fixer_base from itertools import count from ..fixer_util import Assign, Comma, Call, Newline, Name, Number, indentation, suitify, commatize, token, syms, Node, Leaf def assignment_source(num_pre, num_post, LISTNAME, ITERNAME): """ Accepts num_pre and num_post, which are counts of values before and after the starg (not including the starg) Returns a source fit for Assign() from fixer_util """ children = [] pre = str(num_pre) post = str(num_post) # This code builds the assignment source from lib2to3 tree primitives. # It's not very readable, but it seems like the most correct way to do it. if num_pre > 0: pre_part = Node(syms.power, [Name(LISTNAME), Node(syms.trailer, [Leaf(token.LSQB, "["), Node(syms.subscript, [Leaf(token.COLON, ":"), Number(pre)]), Leaf(token.RSQB, "]")])]) children.append(pre_part) children.append(Leaf(token.PLUS, "+", prefix=" ")) main_part = Node(syms.power, [Leaf(token.LSQB, "[", prefix=" "), Name(LISTNAME), Node(syms.trailer, [Leaf(token.LSQB, "["), Node(syms.subscript, [Number(pre) if num_pre > 0 else Leaf(1, ""), Leaf(token.COLON, ":"), Node(syms.factor, [Leaf(token.MINUS, "-"), Number(post)]) if num_post > 0 else Leaf(1, "")]), Leaf(token.RSQB, "]"), Leaf(token.RSQB, "]")])]) children.append(main_part) if num_post > 0: children.append(Leaf(token.PLUS, "+", prefix=" ")) post_part = Node(syms.power, [Name(LISTNAME, prefix=" "), Node(syms.trailer, [Leaf(token.LSQB, "["), Node(syms.subscript, [Node(syms.factor, [Leaf(token.MINUS, "-"), Number(post)]), Leaf(token.COLON, ":")]), Leaf(token.RSQB, "]")])]) children.append(post_part) source = Node(syms.arith_expr, children) return source class FixUnpacking(fixer_base.BaseFix): PATTERN = """ expl=expr_stmt< testlist_star_expr< pre=(any ',')* star_expr< '*' name=NAME > post=(',' any)* [','] > '=' source=any > | impl=for_stmt< 'for' lst=exprlist< pre=(any ',')* star_expr< '*' name=NAME > post=(',' any)* [','] > 'in' it=any ':' suite=any>""" def fix_explicit_context(self, node, results): pre, name, post, source = (results.get(n) for n in ("pre", "name", "post", "source")) pre = [n.clone() for n in pre if n.type == token.NAME] name.prefix = " " post = [n.clone() for n in post if n.type == token.NAME] target = [n.clone() for n in commatize(pre + [name.clone()] + post)] # to make the special-case fix for "*z, = ..." correct with the least # amount of modification, make the left-side into a guaranteed tuple target.append(Comma()) source.prefix = "" setup_line = Assign(Name(self.LISTNAME), Call(Name("list"), [source.clone()])) power_line = Assign(target, assignment_source(len(pre), len(post), self.LISTNAME, self.ITERNAME)) return setup_line, power_line def fix_implicit_context(self, node, results): """ Only example of the implicit context is a for loop, so only fix that. """ pre, name, post, it = (results.get(n) for n in ("pre", "name", "post", "it")) pre = [n.clone() for n in pre if n.type == token.NAME] name.prefix = " " post = [n.clone() for n in post if n.type == token.NAME] target = [n.clone() for n in commatize(pre + [name.clone()] + post)] # to make the special-case fix for "*z, = ..." correct with the least # amount of modification, make the left-side into a guaranteed tuple target.append(Comma()) source = it.clone() source.prefix = "" setup_line = Assign(Name(self.LISTNAME), Call(Name("list"), [Name(self.ITERNAME)])) power_line = Assign(target, assignment_source(len(pre), len(post), self.LISTNAME, self.ITERNAME)) return setup_line, power_line def transform(self, node, results): """ a,b,c,d,e,f,*g,h,i = range(100) changes to _3to2list = list(range(100)) a,b,c,d,e,f,g,h,i, = _3to2list[:6] + [_3to2list[6:-2]] + _3to2list[-2:] and for a,b,*c,d,e in iter_of_iters: do_stuff changes to for _3to2iter in iter_of_iters: _3to2list = list(_3to2iter) a,b,c,d,e, = _3to2list[:2] + [_3to2list[2:-2]] + _3to2list[-2:] do_stuff """ self.LISTNAME = self.new_name("_3to2list") self.ITERNAME = self.new_name("_3to2iter") expl, impl = results.get("expl"), results.get("impl") if expl is not None: setup_line, power_line = self.fix_explicit_context(node, results) setup_line.prefix = expl.prefix power_line.prefix = indentation(expl.parent) setup_line.append_child(Newline()) parent = node.parent i = node.remove() parent.insert_child(i, power_line) parent.insert_child(i, setup_line) elif impl is not None: setup_line, power_line = self.fix_implicit_context(node, results) suitify(node) suite = [k for k in node.children if k.type == syms.suite][0] setup_line.prefix = "" power_line.prefix = suite.children[1].value suite.children[2].prefix = indentation(suite.children[2]) suite.insert_child(2, Newline()) suite.insert_child(2, power_line) suite.insert_child(2, Newline()) suite.insert_child(2, setup_line) results.get("lst").replace(Name(self.ITERNAME, prefix=" ")) 3to2-1.1.1/lib3to2/fixes/fix_unittest.py0000666000000000000000000000115712513010502016467 0ustar rootroot""" Fixer for unittest -> unittest2 """ from lib2to3 import fixer_base from ..fixer_util import Name class FixUnittest(fixer_base.BaseFix): explicit = True PATTERN = """ import_from< 'from' name='unittest' 'import' any > | import_name< 'import' (name='unittest' | dotted_as_name< name='unittest' 'as' any >) > | import_name< 'import' dotted_as_names< any* (name='unittest' | dotted_as_name< name='unittest' 'as' any >) any* > > | power< name='unittest' any* >""" def transform(self, node, results): name = results['name'] name.replace(Name("unittest2", prefix=name.prefix)) 3to2-1.1.1/lib3to2/fixes/fix_throw.py0000666000000000000000000000147312513010502015754 0ustar rootroot"""Fixer for 'g.throw(E(V).with_traceback(T))' -> 'g.throw(E, V, T)'""" from lib2to3 import fixer_base from lib2to3.pytree import Node, Leaf from lib2to3.pgen2 import token from lib2to3.fixer_util import Comma class FixThrow(fixer_base.BaseFix): PATTERN = """ power< any trailer< '.' 'throw' > trailer< '(' args=power< exc=any trailer< '(' val=any* ')' > trailer< '.' 'with_traceback' > trailer< '(' trc=any ')' > > ')' > > """ def transform(self, node, results): syms = self.syms exc, val, trc = (results["exc"], results["val"], results["trc"]) val = val[0] if val else Leaf(token.NAME, "None") val.prefix = trc.prefix = " " kids = [exc.clone(), Comma(), val.clone(), Comma(), trc.clone()] args = results["args"] args.children = kids 3to2-1.1.1/lib3to2/fixes/fix_super.py0000666000000000000000000000462612513010502015752 0ustar rootroot""" Fixer for: def something(self): super() -> def something(self): super(self.__class__, self) """ from lib2to3 import fixer_base from ..fixer_util import Node, Leaf, token, syms, Name, Comma, Dot dot_class = Node(syms.trailer, [Dot(), Name("__class__")]) def get_firstparam(super_node): parent = super_node.parent while parent.type != syms.funcdef and parent.parent: parent = parent.parent if parent.type != syms.funcdef: # super() called without arguments outside of a funcdef return None children = parent.children assert len(children) > 2 params = children[2] assert params.type == syms.parameters if len(params.children) < 3: # Function has no parameters, therefore super() makes no sense here... return None args = params.children[1] if args.type == token.NAME: return args.value elif args.type == syms.typedargslist: assert len(args.children) > 0 if args.children[0].type == token.NAME: return args.children[0].value else: # Probably a '*' return None def get_class_name(super_node): parent = super_node.parent while parent.type != syms.classdef and parent.parent: parent = parent.parent if parent.type != syms.classdef: # super() called without arguments outside of a classdef return None children = parent.children assert len(children) > 2 class_name = children[1] assert class_name.type == token.NAME return class_name.value def insert_args(name, class_name, rparen): parent = rparen.parent if class_name: class_node = Node(syms.power, [Name(class_name)]) else: class_node = Node(syms.power, [Name(name), dot_class.clone()]) idx = parent.children.index(rparen) parent.insert_child(idx, Name(name, prefix=" ")) parent.insert_child(idx, Comma()) parent.insert_child(idx, class_node) class FixSuper(fixer_base.BaseFix): PATTERN = "power< 'super' trailer< '(' rparen=')' > any* >" def transform(self, node, results): param = get_firstparam(node) if param is None: self.cannot_convert(node, "super() with no arguments must be called inside a function that has at least one parameter") return class_name = get_class_name(node) rparen = results["rparen"] insert_args(param, class_name, rparen) 3to2-1.1.1/lib3to2/fixes/fix_str.py0000666000000000000000000000154212513010502015416 0ustar rootroot""" Fixer for: str -> unicode chr -> unichr "spam" -> u"spam" """ import re from lib2to3.pgen2 import token from lib2to3 import fixer_base from lib2to3.fixer_util import Name _mapping = {"chr": "unichr", "str": "unicode"} _literal_re = re.compile(r"[rR]?[\'\"]") class FixStr(fixer_base.BaseFix): order = "pre" run_order = 4 # Run this before bytes objects are converted to str objects PATTERN = "STRING | 'str' | 'chr'" def transform(self, node, results): new = node.clone() if node.type == token.STRING: # Simply add u to the beginning of the literal. if _literal_re.match(new.value): new.value = "u" + new.value return new elif node.type == token.NAME: assert new.value in _mapping new.value = _mapping[new.value] return new 3to2-1.1.1/lib3to2/fixes/fix_setliteral.py0000666000000000000000000000310512513010502016753 0ustar rootroot"""Fixer for '{1, 2, 3}' -> 'set([1, 2, 3])'""" from lib2to3 import fixer_base from lib2to3.pytree import Node, Leaf from lib2to3.pgen2 import token from lib2to3.fixer_util import Name, LParen, RParen def found_dict(node): """Returns true if the node is a dictionary literal (contains a colon)""" # node.children[1] is the dictsetmaker. none of its children may be a colon return any(kid.type == token.COLON for kid in node.children[1].children) class FixSetliteral(fixer_base.BaseFix): PATTERN = """atom< '{' dictsetmaker< args=any* > '}' > | atom< '{' arg=any '}' >""" def match(self, node): results = super(FixSetliteral, self).match(node) if results and not found_dict(node): return results else: return False def transform(self, node, results): syms = self.syms prefix = node.prefix args = results.get("args") arg = results.get("arg") if args: args = [arg.clone() for arg in args] args = Node(syms.atom, [Leaf(token.LSQB, "["), Node(syms.listmaker, args), Leaf(token.RSQB, "]")]) elif arg: arg = arg.clone() arg = Node(syms.atom, [Leaf(token.LSQB, "["), Node(syms.listmaker, [arg]), Leaf(token.RSQB, "]")]) return Node(syms.power, [Name("set"), LParen(), args or arg, RParen()], prefix=prefix) 3to2-1.1.1/lib3to2/fixes/fix_reduce.py0000666000000000000000000000415212513010502016055 0ustar rootroot""" Fixer for: functools.reduce(f, it) -> reduce(f, it) from functools import reduce -> (remove this line) """ from lib2to3 import fixer_base from lib2to3.fixer_util import Call from lib2to3.pytree import Node, Leaf from lib2to3.pgen2 import token class FixReduce(fixer_base.BaseFix): PATTERN = """ power< 'functools' trailer< '.' 'reduce' > args=trailer< '(' arglist< any* > ')' > > | imported=import_from< 'from' 'functools' 'import' 'reduce' > | import_from< 'from' 'functools' 'import' import_as_names< any* in_list='reduce' any* > > """ def transform(self, node, results): syms = self.syms args, imported = (results.get("args"), results.get("imported")) in_list = results.get("in_list") if imported: next = imported.next_sibling prev = imported.prev_sibling parent = imported.parent if next and next.type == token.SEMI: next.remove() next = imported.next_sibling imported.remove() if next is not None and next.type == token.NEWLINE: # nothing after from_import on the line if prev is not None: if prev.type == token.SEMI: prev.remove() elif parent.next_sibling is not None: # nothing before from_import either parent.next_sibling.prefix = imported.prefix parent.remove() elif args: args = args.clone() prefix = node.prefix return Node(syms.power, [Leaf(token.NAME, "reduce"), args], prefix=prefix) elif in_list: next = in_list.next_sibling if next is not None: if next.type == token.COMMA: next.remove() else: prev = in_list.prev_sibling if prev is not None: if prev.type == token.COMMA: prev.remove() in_list.remove() 3to2-1.1.1/lib3to2/fixes/fix_range.py0000666000000000000000000000256712513010502015712 0ustar rootroot""" Fixer for: range(s) -> xrange(s) list(range(s)) -> range(s) """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name, is_probably_builtin from lib2to3.pygram import python_symbols as syms import token def list_called(node): """ Returns the power node that contains list as its first child if node is contained in a list() call, otherwise False. """ parent = node.parent if parent is not None and parent.type == syms.trailer: prev = parent.prev_sibling if prev is not None and \ prev.type == token.NAME and \ prev.value == "list" and \ is_probably_builtin(prev): return prev.parent return False class FixRange(fixer_base.BaseFix): PATTERN = """ power< name='range' trailer< '(' any ')' > > """ def transform(self, node, results): name = results["name"] if not is_probably_builtin(name): return list_call = list_called(node) if list_call: new_node = node.clone() new_node.prefix = list_call.prefix parent = list_call.parent i = list_call.remove() for after in list_call.children[2:]: new_node.append_child(after) parent.insert_child(i, new_node) else: name.replace(Name("xrange", prefix=name.prefix)) 3to2-1.1.1/lib3to2/fixes/fix_raise.py0000666000000000000000000000207312513010502015711 0ustar rootroot"""Fixer for 'raise E(V).with_traceback(T)' -> 'raise E, V, T'""" from lib2to3 import fixer_base from ..fixer_util import Comma, Node, Leaf, token, syms class FixRaise(fixer_base.BaseFix): PATTERN = """ raise_stmt< 'raise' (power< name=any [trailer< '(' val=any* ')' >] [trailer< '.' 'with_traceback' > trailer< '(' trc=any ')' >] > | any) ['from' chain=any] >""" def transform(self, node, results): name, val, trc = (results.get("name"), results.get("val"), results.get("trc")) chain = results.get("chain") if chain is not None: self.warning(node, "explicit exception chaining is not supported in Python 2") chain.prev_sibling.remove() chain.remove() if trc is not None: val = val[0] if val else Leaf(token.NAME, "None") val.prefix = trc.prefix = " " kids = [Leaf(token.NAME, "raise"), name.clone(), Comma(), val.clone(), Comma(), trc.clone()] raise_stmt = Node(syms.raise_stmt, kids) node.replace(raise_stmt) 3to2-1.1.1/lib3to2/fixes/fix_printfunction.py0000666000000000000000000000065412513010502017513 0ustar rootroot""" Fixer for print: from __future__ import print_function. """ from lib2to3 import fixer_base from lib3to2.fixer_util import future_import class FixPrintfunction(fixer_base.BaseFix): explicit = True # Not the preferred way to fix print PATTERN = """ power< 'print' trailer < '(' any* ')' > any* > """ def transform(self, node, results): future_import("print_function", node) 3to2-1.1.1/lib3to2/fixes/fix_print.py0000666000000000000000000001750412513010502015747 0ustar rootroot""" Fixer for print function to print statement print(spam,ham,eggs,sep=sep,end=end,file=file) -> print >>file, sep.join((str(spam),str(ham),str(eggs))),; file.write(end) in the most complicated case. Simpler cases: print() -> print print("spam") -> print "spam" print(1,2,3) -> print 1,2,3 print(1,2,3,end=" ") -> print 1,2,3, print(1,2,3,end="") -> print 1,2,3,; sys.stdout.write("") print(1,2,3,file=file) -> print >>file, 1,2,3 print(1,2,3,sep=" ",end="\n") -> print 1,2,3 """ from __future__ import with_statement # Aiming for 2.5-compatible code from lib2to3 import fixer_base from lib2to3.pytree import Node, Leaf from lib2to3.pygram import python_symbols as syms, token from lib2to3.fixer_util import (Name, FromImport, Newline, Call, Comma, Dot, LParen, RParen, touch_import) import warnings import sys def gen_printargs(lst): """ Accepts a list of all nodes in the print call's trailer. Yields nodes that will be easier to deal with """ for node in lst: if node.type == syms.arglist: # arglist>", prefix=" ")) lst.append(file.clone()) lst.append(Comma()) def add_sep_part(sep, pos, lst): if sep is not None and not isNone(sep) and \ not (sep.type == token.STRING and sep.value in ("' '", '" "')): temp = [] for arg in pos: temp.append(_unicode(arg.clone())) if sys.version_info >= (2, 6): warnings.warn("Calling unicode() on what may be a bytes object") temp.append(Comma()) del temp[-1] sep = sep.clone() sep.prefix = " " args = Node(syms.listmaker, temp) new_list = Node(syms.atom, [Leaf(token.LSQB, "["), args, Leaf(token.RSQB, "]")]) join_arg = Node(syms.trailer, [LParen(), new_list, RParen()]) sep_join = Node(syms.power, [sep, Node(syms.trailer, [Dot(), Name("join")])]) lst.append(sep_join) lst.append(join_arg) else: if pos: pos[0].prefix = " " for arg in pos: lst.append(arg.clone()) lst.append(Comma()) del lst[-1] def add_end_part(end, file, parent, loc): if isNone(end): return if end.type == token.STRING and end.value in ("' '", '" "', "u' '", 'u" "', "b' '", 'b" "'): return if file is None: touch_import(None, "sys", parent) file = Node(syms.power, [Name("sys"), Node(syms.trailer, [Dot(), Name("stdout")])]) end_part = Node(syms.power, [file, Node(syms.trailer, [Dot(), Name("write")]), Node(syms.trailer, [LParen(), end, RParen()])]) end_part.prefix = " " parent.insert_child(loc, Leaf(token.SEMI, ";")) parent.insert_child(loc+1, end_part) def replace_print(pos, opts, old_node=None): """ Replace old_node with a new statement. Also hacks in the "end" functionality. """ new_node = new_print(*pos, **opts) end = None if "end" not in opts else opts["end"].clone() file = None if "file" not in opts else opts["file"].clone() if old_node is None: parent = Node(syms.simple_stmt, [Leaf(token.NEWLINE, "\n")]) i = 0 else: parent = old_node.parent i = old_node.remove() parent.insert_child(i, new_node) if end is not None and not (end.type == token.STRING and \ end.value in ("'\\n'", '"\\n"')): add_end_part(end, file, parent, i+1) return new_node def new_print(*pos, **opts): """ Constructs a new print_stmt node args is all positional arguments passed to print() kwargs contains zero or more of the following mappings: 'sep': some string 'file': some file-like object that supports the write() method 'end': some string """ children = [Name("print")] sep = None if "sep" not in opts else opts["sep"] file = None if "file" not in opts else opts["file"] end = None if "end" not in opts else opts["end"] add_file_part(file, children) add_sep_part(sep, pos, children) if end is not None and not isNone(end): if not end.value in ('"\\n"', "'\\n'"): children.append(Comma()) return Node(syms.print_stmt, children) def map_printargs(args): """ Accepts a list of all nodes in the print call's trailer. Returns {'pos':[all,pos,args], 'sep':sep, 'end':end, 'file':file} """ printargs = [arg for arg in gen_printargs(args)] mapping = {} pos = [] for arg in printargs: if arg.type == syms.argument: kids = arg.children assert kids[0].type == token.NAME, repr(arg) assert len(kids) > 1, repr(arg) assert str(kids[0].value) in ("sep", "end", "file") assert str(kids[0].value) not in mapping, mapping mapping[str(kids[0].value)] = kids[2] elif arg.type == token.STAR: return (None, None) else: pos.append(arg) return (pos, mapping) class FixPrint(fixer_base.BaseFix): PATTERN = """ power< 'print' parens=trailer < '(' args=any* ')' > any* > """ def match(self, node): """ Since the tree needs to be fixed once and only once if and only if it matches, then we can start discarding matches after we make the first. """ return super(FixPrint,self).match(node) def transform(self, node, results): args = results.get("args") if not args: parens = results.get("parens") parens.remove() return pos, opts = map_printargs(args) if pos is None or opts is None: self.cannot_convert(node, "-fprint does not support argument unpacking. fix using -xprint and then again with -fprintfunction.") return if "file" in opts and \ "end" in opts and \ opts["file"].type != token.NAME: self.warning(opts["file"], "file is not a variable name; "\ "print fixer suggests to bind the file to a variable "\ "name first before passing it to print function") try: with warnings.catch_warnings(record=True) as w: new_node = replace_print(pos, opts, old_node=node) if len(w) > 0: self.warning(node, "coercing to unicode even though this may be a bytes object") except AttributeError: # Python 2.5 doesn't have warnings.catch_warnings, so we're in Python 2.5 code here... new_node = replace_print(pos, dict([(bytes(k), opts[k]) for k in opts]), old_node=node) new_node.prefix = node.prefix 3to2-1.1.1/lib3to2/fixes/fix_open.py0000666000000000000000000000050412513010502015544 0ustar rootroot""" Fixer for open(...) -> io.open(...) """ from lib2to3 import fixer_base from ..fixer_util import touch_import, is_probably_builtin class FixOpen(fixer_base.BaseFix): PATTERN = """'open'""" def transform(self, node, results): if is_probably_builtin(node): touch_import("io", "open", node) 3to2-1.1.1/lib3to2/fixes/fix_numliterals.py0000666000000000000000000000436312513010502017151 0ustar rootroot""" Fixer for: 0b111101101 -> __builtins__.long("111101101", 2) 0o755 -> 0755 """ import re from lib2to3.pgen2 import token from lib2to3 import fixer_base from lib2to3.pygram import python_symbols as syms from lib2to3.pytree import Node from lib2to3.fixer_util import Number, Call, Attr, String, Name, ArgList, Comma baseMAPPING = {'b':2, 'o':8, 'x':16} def base(literal): """Returns the base of a valid py3k literal.""" literal = literal.strip() # All literals that do not start with 0, or are 1 or more zeros. if not literal.startswith("0") or re.match(r"0+$",literal): return 10 elif literal[1] not in "box": return 0 return baseMAPPING[literal[1]] class FixNumliterals(fixer_base.BaseFix): # We need to modify all numeric literals except floats, complex. def unmatch(self, node): """Don't match complex numbers, floats, or base-10 ints""" val = node.value for bad in "jJ+-.": if bad in val: return bad base_ = base(val) return base_ == 10 or base_ == 16 def match(self, node): """Match number literals that are not excluded by self.unmatch""" return (node.type == token.NUMBER) and not self.unmatch(node) def transform(self, node, results): """ Call __builtins__.long() with the value and the base of the value. This works because 0b10 is int("10", 2), 0o10 is int("10", 8), etc. """ val = node.value base_ = base(val) if base_ == 8: assert val.strip().startswith("0o") or \ val.strip().startswith("0O"), "Invalid format for octal literal" node.changed() node.value = "".join(("0",val[2:])) elif base_ == 2: assert val.startswith("0") and val[1] in "bB", \ "Invalid format for binary literal" # __builtins__.long func_name = Node(syms.power, Attr(Name("__builtins__"), \ Name("long"))) # ("...", 2) func_args = [String("".join(("\"", val.strip()[2:], "\""))), \ Comma(), Number(2, prefix=" ")] new_node = Call(func_name, func_args, node.prefix) return new_node 3to2-1.1.1/lib3to2/fixes/fix_next.py0000666000000000000000000000230412513010502015561 0ustar rootroot""" Fixer for: it.__next__() -> it.next(). next(it) -> it.next(). """ from lib2to3.pgen2 import token from lib2to3.pygram import python_symbols as syms from lib2to3 import fixer_base from lib2to3.fixer_util import Name, Call, find_binding, Attr bind_warning = "Calls to builtin next() possibly shadowed by global binding" class FixNext(fixer_base.BaseFix): PATTERN = """ power< base=any+ trailer< '.' attr='__next__' > any* > | power< head='next' trailer< '(' arg=any ')' > any* > | classdef< 'class' base=any+ ':' suite< any* funcdef< 'def' attr='__next__' parameters< '(' NAME ')' > any+ > any* > > """ def transform(self, node, results): assert results base = results.get("base") attr = results.get("attr") head = results.get("head") arg_ = results.get("arg") if arg_: arg = arg_.clone() head.replace(Attr(Name(str(arg),prefix=head.prefix), Name("next"))) arg_.remove() elif base: attr.replace(Name("next", prefix=attr.prefix)) 3to2-1.1.1/lib3to2/fixes/fix_newstyle.py0000666000000000000000000000141312513010502016455 0ustar rootroot""" Fixer for "class Foo: ..." -> "class Foo(object): ..." """ from lib2to3 import fixer_base from ..fixer_util import Node, Leaf, token, syms, LParen, RParen, Name def insert_object(node, idx): node.insert_child(idx, RParen()) node.insert_child(idx, Name("object")) node.insert_child(idx, LParen()) class FixNewstyle(fixer_base.BaseFix): PATTERN = "classdef< 'class' NAME [paren='('] [')'] colon=':' any >" def transform(self, node, results): if 'paren' in results: paren = results['paren'] idx = node.children.index(paren) node.insert_child(idx + 1, Name("object")) else: colon = results['colon'] idx = node.children.index(colon) insert_object(node, idx) 3to2-1.1.1/lib3to2/fixes/fix_methodattrs.py0000666000000000000000000000103512513010502017141 0ustar rootroot""" Fixer for method.__X__ -> method.im_X """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name MAP = { "__func__" : "im_func", "__self__" : "im_self" # Fortunately, im_self.__class__ == im_class in 2.5. } class FixMethodattrs(fixer_base.BaseFix): PATTERN = """ power< any+ trailer< '.' attr=('__func__' | '__self__') > any* > """ def transform(self, node, results): attr = results["attr"][0] new = str(MAP[attr.value]) attr.replace(Name(new, prefix=attr.prefix)) 3to2-1.1.1/lib3to2/fixes/fix_metaclass.py0000666000000000000000000000653612513010502016572 0ustar rootroot""" Fixer for (metaclass=X) -> __metaclass__ = X Some semantics (see PEP 3115) may be altered in the translation.""" from lib2to3 import fixer_base from ..fixer_util import Name, syms, Node, Leaf, Newline, find_root, indentation, suitify from lib2to3.pygram import token def has_metaclass(parent): results = None for node in parent.children: kids = node.children if node.type == syms.argument: if kids[0] == Leaf(token.NAME, "metaclass") and \ kids[1] == Leaf(token.EQUAL, "=") and \ kids[2]: #Hack to avoid "class X(=):" with this case. results = [node] + kids break elif node.type == syms.arglist: # Argument list... loop through it looking for: # Node(*, [*, Leaf(token.NAME, u"metaclass"), Leaf(token.EQUAL, u"="), Leaf(*, *)] for child in node.children: if results: break if child.type == token.COMMA: #Store the last comma, which precedes the metaclass comma = child elif type(child) == Node: meta = equal = name = None for arg in child.children: if arg == Leaf(token.NAME, "metaclass"): #We have the (metaclass) part meta = arg elif meta and arg == Leaf(token.EQUAL, "="): #We have the (metaclass=) part equal = arg elif meta and equal: #Here we go, we have (metaclass=X) name = arg results = (comma, meta, equal, name) break return results class FixMetaclass(fixer_base.BaseFix): PATTERN = """ classdef """ def transform(self, node, results): meta_results = has_metaclass(node) if not meta_results: return for meta in meta_results: meta.remove() target = Leaf(token.NAME, "__metaclass__") equal = Leaf(token.EQUAL, "=", prefix=" ") # meta is the last item in what was returned by has_metaclass(): name name = meta name.prefix = " " stmt_node = Node(syms.atom, [target, equal, name]) suitify(node) left_ind, right_ind = 0, 0 for (ind, item) in enumerate(node.children): if item.type == token.LPAR: left_ind = ind elif item.type == token.RPAR: right_ind = ind if item.type == syms.suite: for stmt in item.children: if stmt.type == token.INDENT: # Insert, in reverse order, the statement, a newline, # and an indent right after the first indented line loc = item.children.index(stmt) + 1 # Keep consistent indentation form ident = Leaf(token.INDENT, stmt.value) item.insert_child(loc, ident) item.insert_child(loc, Newline()) item.insert_child(loc, stmt_node) break if right_ind - left_ind == 1: node.insert_child(left_ind + 1, Name("object")) 3to2-1.1.1/lib3to2/fixes/fix_memoryview.py0000666000000000000000000000104312513010502017005 0ustar rootroot""" Fixer for memoryview(s) -> buffer(s). Explicit because some memoryview methods are invalid on buffer objects. """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name class FixMemoryview(fixer_base.BaseFix): explicit = True # User must specify that they want this. PATTERN = """ power< name='memoryview' trailer< '(' [any] ')' > rest=any* > """ def transform(self, node, results): name = results["name"] name.replace(Name("buffer", prefix=name.prefix)) 3to2-1.1.1/lib3to2/fixes/fix_kwargs.py0000666000000000000000000001347012513010502016107 0ustar rootroot""" Fixer for Python 3 function parameter syntax This fixer is rather sensitive to incorrect py3k syntax. """ # Note: "relevant" parameters are parameters following the first STAR in the list. from lib2to3 import fixer_base from ..fixer_util import token, indentation, suitify, String, Newline, Comma, DoubleStar, Name _assign_template = "%(name)s = %(kwargs)s['%(name)s']; del %(kwargs)s['%(name)s']" _if_template = "if '%(name)s' in %(kwargs)s: %(assign)s" _else_template = "else: %(name)s = %(default)s" _kwargs_default_name = "_3to2kwargs" def gen_params(raw_params): """ Generator that yields tuples of (name, default_value) for each parameter in the list If no default is given, then it is default_value is None (not Leaf(token.NAME, 'None')) """ assert raw_params[0].type == token.STAR and len(raw_params) > 2 curr_idx = 2 # the first place a keyword-only parameter name can be is index 2 max_idx = len(raw_params) while curr_idx < max_idx: curr_item = raw_params[curr_idx] prev_item = curr_item.prev_sibling if curr_item.type != token.NAME: curr_idx += 1 continue if prev_item is not None and prev_item.type == token.DOUBLESTAR: break name = curr_item.value nxt = curr_item.next_sibling if nxt is not None and nxt.type == token.EQUAL: default_value = nxt.next_sibling curr_idx += 2 else: default_value = None yield (name, default_value) curr_idx += 1 def remove_params(raw_params, kwargs_default=_kwargs_default_name): """ Removes all keyword-only args from the params list and a bare star, if any. Does not add the kwargs dict if needed. Returns True if more action is needed, False if not (more action is needed if no kwargs dict exists) """ assert raw_params[0].type == token.STAR if raw_params[1].type == token.COMMA: raw_params[0].remove() raw_params[1].remove() kw_params = raw_params[2:] else: kw_params = raw_params[3:] for param in kw_params: if param.type != token.DOUBLESTAR: param.remove() else: return False else: return True def needs_fixing(raw_params, kwargs_default=_kwargs_default_name): """ Returns string with the name of the kwargs dict if the params after the first star need fixing Otherwise returns empty string """ found_kwargs = False needs_fix = False for t in raw_params[2:]: if t.type == token.COMMA: # Commas are irrelevant at this stage. continue elif t.type == token.NAME and not found_kwargs: # Keyword-only argument: definitely need to fix. needs_fix = True elif t.type == token.NAME and found_kwargs: # Return 'foobar' of **foobar, if needed. return t.value if needs_fix else '' elif t.type == token.DOUBLESTAR: # Found either '*' from **foobar. found_kwargs = True else: # Never found **foobar. Return a synthetic name, if needed. return kwargs_default if needs_fix else '' class FixKwargs(fixer_base.BaseFix): run_order = 7 # Run after function annotations are removed PATTERN = "funcdef< 'def' NAME parameters< '(' arglist=typedargslist< params=any* > ')' > ':' suite=any >" def transform(self, node, results): params_rawlist = results["params"] for i, item in enumerate(params_rawlist): if item.type == token.STAR: params_rawlist = params_rawlist[i:] break else: return # params is guaranteed to be a list starting with *. # if fixing is needed, there will be at least 3 items in this list: # [STAR, COMMA, NAME] is the minimum that we need to worry about. new_kwargs = needs_fixing(params_rawlist) # new_kwargs is the name of the kwargs dictionary. if not new_kwargs: return suitify(node) # At this point, params_rawlist is guaranteed to be a list # beginning with a star that includes at least one keyword-only param # e.g., [STAR, NAME, COMMA, NAME, COMMA, DOUBLESTAR, NAME] or # [STAR, COMMA, NAME], or [STAR, COMMA, NAME, COMMA, DOUBLESTAR, NAME] # Anatomy of a funcdef: ['def', 'name', parameters, ':', suite] # Anatomy of that suite: [NEWLINE, INDENT, first_stmt, all_other_stmts] # We need to insert our new stuff before the first_stmt and change the # first_stmt's prefix. suite = node.children[4] first_stmt = suite.children[2] ident = indentation(first_stmt) for name, default_value in gen_params(params_rawlist): if default_value is None: suite.insert_child(2, Newline()) suite.insert_child(2, String(_assign_template %{'name':name, 'kwargs':new_kwargs}, prefix=ident)) else: suite.insert_child(2, Newline()) suite.insert_child(2, String(_else_template %{'name':name, 'default':default_value}, prefix=ident)) suite.insert_child(2, Newline()) suite.insert_child(2, String(_if_template %{'assign':_assign_template %{'name':name, 'kwargs':new_kwargs}, 'name':name, 'kwargs':new_kwargs}, prefix=ident)) first_stmt.prefix = ident suite.children[2].prefix = "" # Now, we need to fix up the list of params. must_add_kwargs = remove_params(params_rawlist) if must_add_kwargs: arglist = results['arglist'] if len(arglist.children) > 0 and arglist.children[-1].type != token.COMMA: arglist.append_child(Comma()) arglist.append_child(DoubleStar(prefix=" ")) arglist.append_child(Name(new_kwargs)) 3to2-1.1.1/lib3to2/fixes/fix_itertools.py0000666000000000000000000000331012513010502016625 0ustar rootroot""" Fixer for: map -> itertools.imap filter -> itertools.ifilter zip -> itertools.izip itertools.filterfalse -> itertools.ifilterfalse """ from lib2to3 import fixer_base from lib2to3.pytree import Node from lib2to3.fixer_util import touch_import, is_probably_builtin class FixItertools(fixer_base.BaseFix): PATTERN = """ power< names=('map' | 'filter' | 'zip') any*> | import_from< 'from' 'itertools' 'import' imports=any > | power< 'itertools' trailer< '.' f='filterfalse' any* > > | power< f='filterfalse' any* > any* """ def transform(self, node, results): syms = self.syms imports = results.get("imports") f = results.get("f") names = results.get("names") if imports: if imports.type == syms.import_as_name or not imports.children: children = [imports] else: children = imports.children for child in children[::2]: if isinstance(child, Node): for kid in child.children: if kid.value == "filterfalse": kid.changed() kid.value = "ifilterfalse" break elif child.value == "filterfalse": child.changed() child.value = "ifilterfalse" break elif names: for name in names: if is_probably_builtin(name): name.value = "i" + name.value touch_import("itertools", name.value, node) elif f: f.changed() f.value = "ifilterfalse" 3to2-1.1.1/lib3to2/fixes/fix_intern.py0000666000000000000000000000701712513010502016110 0ustar rootroot""" Fixer for sys.intern(s) -> intern(s). """ from lib2to3 import pytree from lib2to3 import fixer_base from lib2to3.fixer_util import Name, BlankLine, find_binding, find_root class FixIntern(fixer_base.BaseFix): PATTERN = """ power< 'sys' trailer < '.' 'intern' > trailer< lpar='(' ( not(arglist | argument) any ','> ) rpar=')' > after=any* > | import_from< 'from' 'sys' 'import' import_as_names< pre=any* binding='intern' post=any* > any* > | import_from< 'from' 'sys' 'import' simple='intern' > """ def transform(self, node, results): name = results.get("name") binding = results.get("binding") pre = results.get("pre") post = results.get("post") simple = results.get("simple") if simple: binding = find_binding("intern", find_root(node), "sys") binding.remove() return if binding: if not pre and not post: new_binding = find_binding("intern", find_root(node), "sys") new_binding.remove() return elif not pre and post: for ch in node.children: if type(ch) == pytree.Node: assert ch.children[0].prefix + "intern" \ == str(ch.children[0]) ch.children[0].remove() # intern assert ch.children[0].prefix + "," \ == str(ch.children[0]) ch.children[0].remove() # , return elif not post and pre: for ch in node.children: if type(ch) == pytree.Node: assert ch.children[-1].prefix + "intern" \ == str(ch.children[-1]) ch.children[-1].remove() # intern assert ch.children[-1].prefix + "," \ == str(ch.children[-1]) ch.children[-1].remove() # , return elif post and pre: for ch in node.children: if type(ch) == pytree.Node: for ch_ in ch.children: if ch_ and ch_.prefix + "intern" == str(ch_): last_ch_ = ch_.prev_sibling ch_.remove() # intern assert last_ch_.prefix + "," \ == str(last_ch_) last_ch_.remove() # , return syms = self.syms obj = results["obj"].clone() if obj.type == syms.arglist: newarglist = obj.clone() else: newarglist = pytree.Node(syms.arglist, [obj.clone()]) after = results["after"] if after: after = [n.clone() for n in after] new = pytree.Node(syms.power, [Name("intern")] + [pytree.Node(syms.trailer, [results["lpar"].clone(), newarglist, results["rpar"].clone()] + after)]) new.prefix = node.prefix return new 3to2-1.1.1/lib3to2/fixes/fix_int.py0000666000000000000000000000313312513010502015376 0ustar rootroot""" Fixer for: int -> long 123 -> 123L """ import re from lib2to3 import fixer_base from lib2to3.fixer_util import Name, is_probably_builtin, Number from lib2to3.pgen2 import token baseMAPPING = {'b':2, 'o':8, 'x':16} class FixInt(fixer_base.BaseFix): explicit = True # In most cases, 3.x ints will work just like 2.x ints. PATTERN = "'int' | NUMBER" static_long = Name("long") def base(self, literal): """Returns the base of a valid py3k numeric literal.""" literal = literal.strip() if not literal.startswith("0") or re.match(r"0+$",literal): return 10 elif literal[1] not in "box": return 0 return baseMAPPING[literal[1]] def unmatch(self, node): """Don't match complex numbers, floats, or longs""" val = node.value #For whatever reason, some ints are being matched after we fix them. if val.endswith("L"): return "L" for bad in "jJ+-.": if bad in val: return bad def match(self, node): return super(FixInt, self).match(node) and not self.unmatch(node) def transform(self, node, results): val = node.value if node.type == token.NUMBER and self.base(val) == 10: assert not val[-1] in "lL", "Invalid py3k literal: " + str(val) val += "L" return Number(val, prefix=node.prefix) elif is_probably_builtin(node): assert node.type == token.NAME, "Sanity check failed: " + str(val) new = self.static_long.clone() new.prefix = node.prefix return new 3to2-1.1.1/lib3to2/fixes/fix_input.py0000666000000000000000000000060012513010502015737 0ustar rootroot""" Fixer for input(s) -> raw_input(s). """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name class FixInput(fixer_base.BaseFix): PATTERN = """ power< name='input' trailer< '(' [any] ')' > any* > """ def transform(self, node, results): name = results["name"] name.replace(Name("raw_input", prefix=name.prefix)) 3to2-1.1.1/lib3to2/fixes/fix_imports2.py0000666000000000000000000004010612513010502016364 0ustar rootroot""" Fixer for complicated imports """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name, String, FromImport, Newline, Comma from ..fixer_util import token, syms, Leaf, Node, Star, indentation, ImportAsName TK_BASE_NAMES = ('ACTIVE', 'ALL', 'ANCHOR', 'ARC','BASELINE', 'BEVEL', 'BOTH', 'BOTTOM', 'BROWSE', 'BUTT', 'CASCADE', 'CENTER', 'CHAR', 'CHECKBUTTON', 'CHORD', 'COMMAND', 'CURRENT', 'DISABLED', 'DOTBOX', 'E', 'END', 'EW', 'EXCEPTION', 'EXTENDED', 'FALSE', 'FIRST', 'FLAT', 'GROOVE', 'HIDDEN', 'HORIZONTAL', 'INSERT', 'INSIDE', 'LAST', 'LEFT', 'MITER', 'MOVETO', 'MULTIPLE', 'N', 'NE', 'NO', 'NONE', 'NORMAL', 'NS', 'NSEW', 'NUMERIC', 'NW', 'OFF', 'ON', 'OUTSIDE', 'PAGES', 'PIESLICE', 'PROJECTING', 'RADIOBUTTON', 'RAISED', 'READABLE', 'RIDGE', 'RIGHT', 'ROUND', 'S', 'SCROLL', 'SE', 'SEL', 'SEL_FIRST', 'SEL_LAST', 'SEPARATOR', 'SINGLE', 'SOLID', 'SUNKEN', 'SW', 'StringTypes', 'TOP', 'TRUE', 'TclVersion', 'TkVersion', 'UNDERLINE', 'UNITS', 'VERTICAL', 'W', 'WORD', 'WRITABLE', 'X', 'Y', 'YES', 'wantobjects') PY2MODULES = { 'urllib2' : ( 'AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'AbstractHTTPHandler', 'BaseHandler', 'CacheFTPHandler', 'FTPHandler', 'FileHandler', 'HTTPBasicAuthHandler', 'HTTPCookieProcessor', 'HTTPDefaultErrorHandler', 'HTTPDigestAuthHandler', 'HTTPError', 'HTTPErrorProcessor', 'HTTPHandler', 'HTTPPasswordMgr', 'HTTPPasswordMgrWithDefaultRealm', 'HTTPRedirectHandler', 'HTTPSHandler', 'OpenerDirector', 'ProxyBasicAuthHandler', 'ProxyDigestAuthHandler', 'ProxyHandler', 'Request', 'StringIO', 'URLError', 'UnknownHandler', 'addinfourl', 'build_opener', 'install_opener', 'parse_http_list', 'parse_keqv_list', 'randombytes', 'request_host', 'urlopen'), 'urllib' : ( 'ContentTooShortError', 'FancyURLopener','URLopener', 'basejoin', 'ftperrors', 'getproxies', 'getproxies_environment', 'localhost', 'pathname2url', 'quote', 'quote_plus', 'splitattr', 'splithost', 'splitnport', 'splitpasswd', 'splitport', 'splitquery', 'splittag', 'splittype', 'splituser', 'splitvalue', 'thishost', 'unquote', 'unquote_plus', 'unwrap', 'url2pathname', 'urlcleanup', 'urlencode', 'urlopen', 'urlretrieve',), 'urlparse' : ( 'parse_qs', 'parse_qsl', 'urldefrag', 'urljoin', 'urlparse', 'urlsplit', 'urlunparse', 'urlunsplit'), 'dbm' : ( 'ndbm', 'gnu', 'dumb'), 'anydbm' : ( 'error', 'open'), 'whichdb' : ( 'whichdb',), 'BaseHTTPServer' : ( 'BaseHTTPRequestHandler', 'HTTPServer'), 'CGIHTTPServer' : ( 'CGIHTTPRequestHandler',), 'SimpleHTTPServer' : ( 'SimpleHTTPRequestHandler',), 'FileDialog' : TK_BASE_NAMES + ( 'FileDialog', 'LoadFileDialog', 'SaveFileDialog', 'dialogstates', 'test'), 'tkFileDialog' : ( 'Directory', 'Open', 'SaveAs', '_Dialog', 'askdirectory', 'askopenfile', 'askopenfilename', 'askopenfilenames', 'askopenfiles', 'asksaveasfile', 'asksaveasfilename'), 'SimpleDialog' : TK_BASE_NAMES + ( 'SimpleDialog',), 'tkSimpleDialog' : TK_BASE_NAMES + ( 'askfloat', 'askinteger', 'askstring', 'Dialog'), 'SimpleXMLRPCServer' : ( 'CGIXMLRPCRequestHandler', 'SimpleXMLRPCDispatcher', 'SimpleXMLRPCRequestHandler', 'SimpleXMLRPCServer', 'list_public_methods', 'remove_duplicates', 'resolve_dotted_attribute'), 'DocXMLRPCServer' : ( 'DocCGIXMLRPCRequestHandler', 'DocXMLRPCRequestHandler', 'DocXMLRPCServer', 'ServerHTMLDoc','XMLRPCDocGenerator'), } MAPPING = { 'urllib.request' : ('urllib2', 'urllib'), 'urllib.error' : ('urllib2', 'urllib'), 'urllib.parse' : ('urllib2', 'urllib', 'urlparse'), 'dbm.__init__' : ('anydbm', 'whichdb'), 'http.server' : ('CGIHTTPServer', 'SimpleHTTPServer', 'BaseHTTPServer'), 'tkinter.filedialog' : ('tkFileDialog', 'FileDialog'), 'tkinter.simpledialog' : ('tkSimpleDialog', 'SimpleDialog'), 'xmlrpc.server' : ('DocXMLRPCServer', 'SimpleXMLRPCServer'), } # helps match 'http', as in 'from http.server import ...' simple_name = "name='{name}'" # helps match 'server', as in 'from http.server import ...' simple_attr = "attr='{attr}'" # helps match 'HTTPServer', as in 'from http.server import HTTPServer' simple_using = "using='{using}'" # helps match 'urllib.request', as in 'import urllib.request' dotted_name = "dotted_name=dotted_name< {fmt_name} '.' {fmt_attr} >" # helps match 'http.server', as in 'http.server.HTTPServer(...)' power_twoname = "pow=power< {fmt_name} trailer< '.' {fmt_attr} > trailer< '.' using=any > any* >" # helps match 'dbm.whichdb', as in 'dbm.whichdb(...)' power_onename = "pow=power< {fmt_name} trailer< '.' using=any > any* >" # helps match 'from http.server import HTTPServer' # also helps match 'from http.server import HTTPServer, SimpleHTTPRequestHandler' # also helps match 'from http.server import *' from_import = "from_import=import_from< 'from' {modules} 'import' (import_as_name< using=any 'as' renamed=any> | in_list=import_as_names< using=any* > | using='*' | using=NAME) >" # helps match 'import urllib.request' name_import = "name_import=import_name< 'import' ({fmt_name} | in_list=dotted_as_names< imp_list=any* >) >" ############# # WON'T FIX # ############# # helps match 'import urllib.request as name' name_import_rename = "name_import_rename=dotted_as_name< {fmt_name} 'as' renamed=any >" # helps match 'from http import server' from_import_rename = "from_import_rename=import_from< 'from' {fmt_name} 'import' ({fmt_attr} | import_as_name< {fmt_attr} 'as' renamed=any > | in_list=import_as_names< any* ({fmt_attr} | import_as_name< {fmt_attr} 'as' renamed=any >) any* >) >" def all_modules_subpattern(): """ Builds a pattern for all toplevel names (urllib, http, etc) """ names_dot_attrs = [mod.split(".") for mod in MAPPING] ret = "( " + " | ".join([dotted_name.format(fmt_name=simple_name.format(name=mod[0]), fmt_attr=simple_attr.format(attr=mod[1])) for mod in names_dot_attrs]) ret += " | " ret += " | ".join([simple_name.format(name=mod[0]) for mod in names_dot_attrs if mod[1] == "__init__"]) + " )" return ret def all_candidates(name, attr, MAPPING=MAPPING): """ Returns all candidate packages for the name.attr """ dotted = name + '.' + attr assert dotted in MAPPING, "No matching package found." ret = MAPPING[dotted] if attr == '__init__': return ret + (name,) return ret def new_package(name, attr, using, MAPPING=MAPPING, PY2MODULES=PY2MODULES): """ Returns which candidate package for name.attr provides using """ for candidate in all_candidates(name, attr, MAPPING): if using in PY2MODULES[candidate]: break else: candidate = None return candidate def build_import_pattern(mapping1, mapping2): """ mapping1: A dict mapping py3k modules to all possible py2k replacements mapping2: A dict mapping py2k modules to the things they do This builds a HUGE pattern to match all ways that things can be imported """ # py3k: urllib.request, py2k: ('urllib2', 'urllib') yield from_import.format(modules=all_modules_subpattern()) for py3k, py2k in mapping1.items(): name, attr = py3k.split('.') s_name = simple_name.format(name=name) s_attr = simple_attr.format(attr=attr) d_name = dotted_name.format(fmt_name=s_name, fmt_attr=s_attr) yield name_import.format(fmt_name=d_name) yield power_twoname.format(fmt_name=s_name, fmt_attr=s_attr) if attr == '__init__': yield name_import.format(fmt_name=s_name) yield power_onename.format(fmt_name=s_name) yield name_import_rename.format(fmt_name=d_name) yield from_import_rename.format(fmt_name=s_name, fmt_attr=s_attr) def name_import_replacement(name, attr): children = [Name("import")] for c in all_candidates(name.value, attr.value): children.append(Name(c, prefix=" ")) children.append(Comma()) children.pop() replacement = Node(syms.import_name, children) return replacement class FixImports2(fixer_base.BaseFix): run_order = 4 PATTERN = " | \n".join(build_import_pattern(MAPPING, PY2MODULES)) def transform(self, node, results): # The patterns dictate which of these names will be defined name = results.get("name") attr = results.get("attr") if attr is None: attr = Name("__init__") using = results.get("using") in_list = results.get("in_list") imp_list = results.get("imp_list") power = results.get("pow") before = results.get("before") after = results.get("after") d_name = results.get("dotted_name") # An import_stmt is always contained within a simple_stmt simple_stmt = node.parent # The parent is useful for adding new import_stmts parent = simple_stmt.parent idx = parent.children.index(simple_stmt) if any((results.get("from_import_rename") is not None, results.get("name_import_rename") is not None)): self.cannot_convert(node, reason="ambiguity: import binds a single name") elif using is None and not in_list: # import urllib.request, single-name import replacement = name_import_replacement(name, attr) replacement.prefix = node.prefix node.replace(replacement) elif using is None: # import ..., urllib.request, math, http.sever, ... for d_name in imp_list: if d_name.type == syms.dotted_name: name = d_name.children[0] attr = d_name.children[2] elif d_name.type == token.NAME and d_name.value + ".__init__" in MAPPING: name = d_name attr = Name("__init__") else: continue if name.value + "." + attr.value not in MAPPING: continue candidates = all_candidates(name.value, attr.value) children = [Name("import")] for c in candidates: children.append(Name(c, prefix=" ")) children.append(Comma()) children.pop() # Put in the new statement. indent = indentation(simple_stmt) next_stmt = Node(syms.simple_stmt, [Node(syms.import_name, children), Newline()]) parent.insert_child(idx+1, next_stmt) parent.insert_child(idx+1, Leaf(token.INDENT, indent)) # Remove the old imported name test_comma = d_name.next_sibling if test_comma and test_comma.type == token.COMMA: test_comma.remove() elif test_comma is None: test_comma = d_name.prev_sibling if test_comma and test_comma.type == token.COMMA: test_comma.remove() d_name.remove() if not in_list.children: simple_stmt.remove() elif in_list is not None: ########################################################## # "from urllib.request import urlopen, urlretrieve, ..." # # Replace one import statement with potentially many. # ########################################################## packages = dict([(n,[]) for n in all_candidates(name.value, attr.value)]) # Figure out what names need to be imported from what # Add them to a dict to be parsed once we're completely done for imported in using: if imported.type == token.COMMA: continue if imported.type == syms.import_as_name: test_name = imported.children[0].value if len(imported.children) > 2: # 'as' whatever rename = imported.children[2].value else: rename = None elif imported.type == token.NAME: test_name = imported.value rename = None pkg = new_package(name.value, attr.value, test_name) packages[pkg].append((test_name, rename)) # Parse the dict to create new import statements to replace this one imports = [] for new_pkg, names in packages.items(): if not names: # Didn't import anything from that package, move along continue new_names = [] for test_name, rename in names: if rename is None: new_names.append(Name(test_name, prefix=" ")) else: new_names.append(ImportAsName(test_name, rename, prefix=" ")) new_names.append(Comma()) new_names.pop() imports.append(FromImport(new_pkg, new_names)) # Replace this import statement with one of the others replacement = imports.pop() replacement.prefix = node.prefix node.replace(replacement) indent = indentation(simple_stmt) # Add the remainder of the imports as new statements. while imports: next_stmt = Node(syms.simple_stmt, [imports.pop(), Newline()]) parent.insert_child(idx+1, next_stmt) parent.insert_child(idx+1, Leaf(token.INDENT, indent)) elif using.type == token.STAR: # from urllib.request import * nodes = [FromImport(pkg, [Star(prefix=" ")]) for pkg in all_candidates(name.value, attr.value)] replacement = nodes.pop() replacement.prefix = node.prefix node.replace(replacement) indent = indentation(simple_stmt) while nodes: next_stmt = Node(syms.simple_stmt, [nodes.pop(), Newline()]) parent.insert_child(idx+1, next_stmt) parent.insert_child(idx+1, Leaf(token.INDENT, indent)) elif power is not None: # urllib.request.urlopen # Replace it with urllib2.urlopen pkg = new_package(name.value, attr.value, using.value) # Remove the trailer node that contains attr. if pkg: if attr.parent: attr.parent.remove() name.replace(Name(pkg, prefix=name.prefix)) elif using.type == token.NAME: # from urllib.request import urlopen pkg = new_package(name.value, attr.value, using.value) if attr.value == "__init__" and pkg == name.value: # Replacing "from abc import xyz" with "from abc import xyz" # Just leave it alone so as not to mess with other fixers return else: node.replace(FromImport(pkg, [using])) 3to2-1.1.1/lib3to2/fixes/fix_imports.py0000666000000000000000000002604412513010502016307 0ustar rootroot""" Fixer for standard library imports renamed in Python 3 """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name, is_probably_builtin, Newline, does_tree_import from lib2to3.pygram import python_symbols as syms from lib2to3.pgen2 import token from lib2to3.pytree import Node, Leaf from ..fixer_util import NameImport # used in simple_mapping_to_pattern() MAPPING = {"reprlib": "repr", "winreg": "_winreg", "configparser": "ConfigParser", "copyreg": "copy_reg", "queue": "Queue", "socketserver": "SocketServer", "_markupbase": "markupbase", "test.support": "test.test_support", "dbm.bsd": "dbhash", "dbm.ndbm": "dbm", "dbm.dumb": "dumbdbm", "dbm.gnu": "gdbm", "html.parser": "HTMLParser", "html.entities": "htmlentitydefs", "http.client": "httplib", "http.cookies": "Cookie", "http.cookiejar": "cookielib", "tkinter": "Tkinter", "tkinter.dialog": "Dialog", "tkinter._fix": "FixTk", "tkinter.scrolledtext": "ScrolledText", "tkinter.tix": "Tix", "tkinter.constants": "Tkconstants", "tkinter.dnd": "Tkdnd", "tkinter.__init__": "Tkinter", "tkinter.colorchooser": "tkColorChooser", "tkinter.commondialog": "tkCommonDialog", "tkinter.font": "tkFont", "tkinter.messagebox": "tkMessageBox", "tkinter.turtle": "turtle", "urllib.robotparser": "robotparser", "xmlrpc.client": "xmlrpclib", "builtins": "__builtin__", } # generic strings to help build patterns # these variables mean (with http.client.HTTPConnection as an example): # name = http # attr = client # used = HTTPConnection # fmt_name is a formatted subpattern (simple_name_match or dotted_name_match) # helps match 'queue', as in 'from queue import ...' simple_name_match = "name='{name}'" # helps match 'client', to be used if client has been imported from http subname_match = "attr='{attr}'" # helps match 'http.client', as in 'import urllib.request' dotted_name_match = "dotted_name=dotted_name< {fmt_name} '.' {fmt_attr} >" # helps match 'queue', as in 'queue.Queue(...)' power_onename_match = "{fmt_name}" # helps match 'http.client', as in 'http.client.HTTPConnection(...)' power_twoname_match = "power< {fmt_name} trailer< '.' {fmt_attr} > any* >" # helps match 'client.HTTPConnection', if 'client' has been imported from http power_subname_match = "power< {fmt_attr} any* >" # helps match 'from http.client import HTTPConnection' from_import_match = "from_import=import_from< 'from' {fmt_name} 'import' ['('] imported=any [')'] >" # helps match 'from http import client' from_import_submod_match = "from_import_submod=import_from< 'from' {fmt_name} 'import' ({fmt_attr} | import_as_name< {fmt_attr} 'as' renamed=any > | import_as_names< any* ({fmt_attr} | import_as_name< {fmt_attr} 'as' renamed=any >) any* > ) >" # helps match 'import urllib.request' name_import_match = "name_import=import_name< 'import' {fmt_name} > | name_import=import_name< 'import' dotted_as_name< {fmt_name} 'as' renamed=any > >" # helps match 'import http.client, winreg' multiple_name_import_match = "name_import=import_name< 'import' dotted_as_names< names=any* > >" def all_patterns(name): """ Accepts a string and returns a pattern of possible patterns involving that name Called by simple_mapping_to_pattern for each name in the mapping it receives. """ # i_ denotes an import-like node # u_ denotes a node that appears to be a usage of the name if '.' in name: name, attr = name.split('.', 1) simple_name = simple_name_match.format(name=name) simple_attr = subname_match.format(attr=attr) dotted_name = dotted_name_match.format(fmt_name=simple_name, fmt_attr=simple_attr) i_from = from_import_match.format(fmt_name=dotted_name) i_from_submod = from_import_submod_match.format(fmt_name=simple_name, fmt_attr=simple_attr) i_name = name_import_match.format(fmt_name=dotted_name) u_name = power_twoname_match.format(fmt_name=simple_name, fmt_attr=simple_attr) u_subname = power_subname_match.format(fmt_attr=simple_attr) return ' | \n'.join((i_name, i_from, i_from_submod, u_name, u_subname)) else: simple_name = simple_name_match.format(name=name) i_name = name_import_match.format(fmt_name=simple_name) i_from = from_import_match.format(fmt_name=simple_name) u_name = power_onename_match.format(fmt_name=simple_name) return ' | \n'.join((i_name, i_from, u_name)) class FixImports(fixer_base.BaseFix): order = "pre" PATTERN = ' | \n'.join([all_patterns(name) for name in MAPPING]) PATTERN = ' | \n'.join((PATTERN, multiple_name_import_match)) def fix_dotted_name(self, node, mapping=MAPPING): """ Accepts either a DottedName node or a power node with a trailer. If mapping is given, use it; otherwise use our MAPPING Returns a node that can be in-place replaced by the node given """ if node.type == syms.dotted_name: _name = node.children[0] _attr = node.children[2] elif node.type == syms.power: _name = node.children[0] _attr = node.children[1].children[1] name = _name.value attr = _attr.value full_name = name + '.' + attr if not full_name in mapping: return to_repl = mapping[full_name] if '.' in to_repl: repl_name, repl_attr = to_repl.split('.') _name.replace(Name(repl_name, prefix=_name.prefix)) _attr.replace(Name(repl_attr, prefix=_attr.prefix)) elif node.type == syms.dotted_name: node.replace(Name(to_repl, prefix=node.prefix)) elif node.type == syms.power: _name.replace(Name(to_repl, prefix=_name.prefix)) parent = _attr.parent _attr.remove() parent.remove() def fix_simple_name(self, node, mapping=MAPPING): """ Accepts a Name leaf. If mapping is given, use it; otherwise use our MAPPING Returns a node that can be in-place replaced by the node given """ assert node.type == token.NAME, repr(node) if not node.value in mapping: return replacement = mapping[node.value] node.replace(Leaf(token.NAME, str(replacement), prefix=node.prefix)) def fix_submod_import(self, imported, name, node): """ Accepts a list of NAME leafs, a name string, and a node node is given as an argument to BaseFix.transform() NAME leafs come from an import_as_names node (the children) name string is the base name found in node. """ submods = [] missed = [] for attr in imported: dotted = '.'.join((name, attr.value)) if dotted in MAPPING: # get the replacement module to_repl = MAPPING[dotted] if '.' not in to_repl: # it's a simple name, so use a simple replacement. _import = NameImport(Name(to_repl, prefix=" "), attr.value) submods.append(_import) elif attr.type == token.NAME: missed.append(attr.clone()) if not submods: return parent = node.parent node.replace(submods[0]) if len(submods) > 1: start = submods.pop(0) prev = start for submod in submods: parent.append_child(submod) if missed: self.warning(node, "Imported names not known to 3to2 to be part of the package {0}. Leaving those alone... high probability that this code will be incorrect.".format(name)) children = [Name("from"), Name(name, prefix=" "), Name("import", prefix=" "), Node(syms.import_as_names, missed)] orig_stripped = Node(syms.import_from, children) parent.append_child(Newline()) parent.append_child(orig_stripped) def get_dotted_import_replacement(self, name_node, attr_node, mapping=MAPPING, renamed=None): """ For (http, client) given and httplib being the correct replacement, returns (httplib as client, None) For (test, support) given and test.test_support being the replacement, returns (test, test_support as support) """ full_name = name_node.value + '.' + attr_node.value replacement = mapping[full_name] if '.' in replacement: new_name, new_attr = replacement.split('.') if renamed is None: return Name(new_name, prefix=name_node.prefix), Node(syms.dotted_as_name, [Name(new_attr, prefix=attr_node.prefix), Name('as', prefix=" "), attr_node.clone()]) else: return Name(new_name, prefix=name_node.prefix), Name(new_attr, prefix=attr_node.prefix) else: return Node(syms.dotted_as_name, [Name(replacement, prefix=name_node.prefix), Name('as', prefix=' '), Name(attr_node.value, prefix=attr_node.prefix)]), None def transform(self, node, results): from_import = results.get("from_import") from_import_submod = results.get("from_import_submod") name_import = results.get("name_import") dotted_name = results.get("dotted_name") name = results.get("name") names = results.get("names") attr = results.get("attr") imported = results.get("imported") if names: for name in names: if name.type == token.NAME: self.fix_simple_name(name) elif name.type == syms.dotted_as_name: self.fix_simple_name(name.children[0]) if name.children[0].type == token.NAME else \ self.fix_dotted_name(name.children[0]) elif name.type == syms.dotted_name: self.fix_dotted_name(name) elif from_import_submod: renamed = results.get("renamed") new_name, new_attr = self.get_dotted_import_replacement(name, attr, renamed=renamed) if new_attr is not None: name.replace(new_name) attr.replace(new_attr) else: children = [Name("import"), new_name] node.replace(Node(syms.import_name, children, prefix=node.prefix)) elif dotted_name: self.fix_dotted_name(dotted_name) elif name_import or from_import: self.fix_simple_name(name) elif name and not attr: if does_tree_import(None, MAPPING[name.value], node) and \ is_probably_builtin(name): self.fix_simple_name(name) elif name and attr: # Note that this will fix a dotted name that was never imported. This will probably not matter. self.fix_dotted_name(node) elif imported and imported.type == syms.import_as_names: self.fix_submod_import(imported=imported.children, node=node, name=name.value) 3to2-1.1.1/lib3to2/fixes/fix_getcwd.py0000666000000000000000000000154112513010502016062 0ustar rootroot""" Fixer for os.getcwd() -> os.getcwdu(). Also warns about "from os import getcwd", suggesting the above form. """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name class FixGetcwd(fixer_base.BaseFix): PATTERN = """ power< 'os' trailer< dot='.' name='getcwd' > any* > | import_from< 'from' 'os' 'import' bad='getcwd' > """ def transform(self, node, results): if "name" in results: name = results["name"] name.replace(Name("getcwdu", prefix=name.prefix)) elif "bad" in results: # Can't convert to getcwdu and then expect to catch every use. self.cannot_convert(node, "import os, use os.getcwd() instead.") return else: raise ValueError("For some reason, the pattern matcher failed.") 3to2-1.1.1/lib3to2/fixes/fix_funcattrs.py0000666000000000000000000000076612513010502016626 0ustar rootroot""" Fixer for f.__x__ -> f.func_x. """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name class FixFuncattrs(fixer_base.BaseFix): PATTERN = """ power< any+ trailer< '.' attr=('__closure__' | '__globals__' | '__defaults__' | '__code__' ) > any* > """ def transform(self, node, results): attr = results["attr"][0] attr.replace(Name(("func_%s" % attr.value.strip("_")), prefix=attr.prefix)) 3to2-1.1.1/lib3to2/fixes/fix_fullargspec.py0000666000000000000000000000066012513010502017115 0ustar rootroot""" Fixer for getfullargspec -> getargspec """ from lib2to3 import fixer_base from ..fixer_util import Name warn_msg = "some of the values returned by getfullargspec are not valid in Python 2 and have no equivalent." class FixFullargspec(fixer_base.BaseFix): PATTERN = "'getfullargspec'" def transform(self, node, results): self.warning(node, warn_msg) return Name("getargspec", prefix=node.prefix) 3to2-1.1.1/lib3to2/fixes/fix_features.py0000666000000000000000000000513412513010502016425 0ustar rootroot""" Warn about features that are not present in Python 2.5, giving a message that points to the earliest version of Python 2.x (or 3.x, if none) that supports it """ from .feature_base import Feature, Features from lib2to3 import fixer_base FEATURES = [ #(FeatureName, # FeaturePattern, # FeatureMinVersion, #), ("memoryview", "power < 'memoryview' trailer < '(' any* ')' > any* >", "2.7", ), ("numbers", """import_from< 'from' 'numbers' 'import' any* > | import_name< 'import' ('numbers' dotted_as_names< any* 'numbers' any* >) >""", "2.6", ), ("abc", """import_name< 'import' ('abc' dotted_as_names< any* 'abc' any* >) > | import_from< 'from' 'abc' 'import' any* >""", "2.6", ), ("io", """import_name< 'import' ('io' dotted_as_names< any* 'io' any* >) > | import_from< 'from' 'io' 'import' any* >""", "2.6", ), ("bin", "power< 'bin' trailer< '(' any* ')' > any* >", "2.6", ), ("formatting", "power< any trailer< '.' 'format' > trailer< '(' any* ')' > >", "2.6", ), ("nonlocal", "global_stmt< 'nonlocal' any* >", "3.0", ), ("with_traceback", "trailer< '.' 'with_traceback' >", "3.0", ), ] class FixFeatures(fixer_base.BaseFix): run_order = 9 # Wait until all other fixers have run to check for these # To avoid spamming, we only want to warn for each feature once. features_warned = set() # Build features from the list above features = Features([Feature(name, pattern, version) for \ name, pattern, version in FEATURES]) PATTERN = features.PATTERN def match(self, node): to_ret = super(FixFeatures, self).match(node) # We want the mapping only to tell us the node's specific information. try: del to_ret['node'] except Exception: # We want it to delete the 'node' from the results # if it's there, so we don't care if it fails for normal reasons. pass return to_ret def transform(self, node, results): for feature_name in results: if feature_name in self.features_warned: continue else: curr_feature = self.features[feature_name] if curr_feature.version >= "3": fail = self.cannot_convert else: fail = self.warning fail(node, reason=curr_feature.message_text()) self.features_warned.add(feature_name) 3to2-1.1.1/lib3to2/fixes/fix_except.py0000666000000000000000000000045112513010502016074 0ustar rootroot""" Fixer for except E as T -> except E, T """ from lib2to3 import fixer_base from lib2to3.fixer_util import Comma class FixExcept(fixer_base.BaseFix): PATTERN = """except_clause< 'except' any as='as' any >""" def transform(self, node, results): results["as"].replace(Comma()) 3to2-1.1.1/lib3to2/fixes/fix_division.py0000666000000000000000000000151712513010502016434 0ustar rootroot""" Fixer for division: from __future__ import division if needed """ from lib2to3 import fixer_base from lib3to2.fixer_util import token, future_import def match_division(node): """ __future__.division redefines the meaning of a single slash for division, so we match that and only that. """ slash = token.SLASH return node.type == slash and not node.next_sibling.type == slash and \ not node.prev_sibling.type == slash class FixDivision(fixer_base.BaseFix): def match(self, node): """ Since the tree needs to be fixed once and only once if and only if it matches, then we can start discarding matches after we make the first. """ return match_division(node) def transform(self, node, results): future_import("division", node) 3to2-1.1.1/lib3to2/fixes/fix_dctsetcomp.py0000666000000000000000000000271612513010502016757 0ustar rootroot""" Fixer for dictcomp and setcomp: {foo comp_for} -> set((foo comp_for)) {foo:bar comp_for} -> dict(((foo, bar) comp_for))""" from lib2to3 import fixer_base from lib2to3.pytree import Node, Leaf from lib2to3.pygram import python_symbols as syms from lib2to3.pgen2 import token from lib2to3.fixer_util import parenthesize, Name, Call, LParen, RParen from ..fixer_util import commatize def tup(args): return parenthesize(Node(syms.testlist_gexp, commatize(args))) class FixDctsetcomp(fixer_base.BaseFix): PATTERN = """atom< '{' dictsetmaker< n1=any [col=':' n2=any] comp_for=comp_for< 'for' any 'in' any [comp_if<'if' any>] > > '}' >""" def transform(self, node, results): comp_for = results.get("comp_for").clone() is_dict = bool(results.get("col")) # is it a dict? n1 = results.get("n1").clone() if is_dict: n2 = results.get("n2").clone() n2.prefix = " " impl_assign = tup((n1, n2)) else: impl_assign = n1 our_gencomp = Node(syms.listmaker, [(impl_assign),(comp_for)]) if is_dict: new_node = Node(syms.power, [Name("dict"), parenthesize(Node(syms.atom, [our_gencomp]))]) else: new_node = Node(syms.power, [Name("set"), parenthesize(Node(syms.atom, [our_gencomp]))]) new_node.prefix = node.prefix return new_node 3to2-1.1.1/lib3to2/fixes/fix_collections.py0000666000000000000000000000146512513010502017130 0ustar rootroot""" Fixer for: collections.UserDict -> UserDict.UserDict collections.UserList -> UserList.UserList collections.UserString -> UserString.UserString """ from lib2to3 import fixer_base from ..fixer_util import Name, syms, touch_import class FixCollections(fixer_base.BaseFix): explicit = True PATTERN = """import_from< 'from' collections='collections' 'import' name=('UserDict' | 'UserList' | 'UserString') > | power< collections='collections' trailer< '.' name=('UserDict' | 'UserList' | 'UserString') > any* >""" def transform(self, node, results): collections = results["collections"] name = results["name"][0] collections.replace(Name(name.value, prefix=collections.prefix)) if node.type == syms.power: touch_import(None, name.value, node) 3to2-1.1.1/lib3to2/fixes/fix_classdecorator.py0000666000000000000000000000312712513010502017617 0ustar rootroot""" Fixer to remove class decorators """ from lib2to3 import fixer_base from lib2to3.fixer_util import Call, Assign, String, Newline from ..fixer_util import Leaf, Node, token, syms, indentation class FixClassdecorator(fixer_base.BaseFix): PATTERN = """ decorated < one_dec=decorator < any* > cls=classdef < 'class' name=any any* > > | decorated < decorators < decs=decorator+ > cls=classdef < 'class' name=any any* > > """ def transform(self, node, results): singleton = results.get("one_dec") classdef = results["cls"] decs = [results["one_dec"]] if results.get("one_dec") is not None else results["decs"] dec_strings = [str(dec).strip()[1:] for dec in decs] assign = "" for dec in dec_strings: assign += dec assign += "(" assign += results["name"].value for dec in dec_strings: assign += ")" assign = String(results["name"].value + " = " + assign) assign_statement = Node(syms.simple_stmt, [assign, Newline(), Newline()]) prefix = None for dec in decs: if prefix is None: prefix = dec.prefix dec.remove() classdef.prefix = prefix i = indentation(node) pos = node.children.index(classdef) + 1 if classdef.children[-1].children[-1].type == token.DEDENT: del classdef.children[-1].children[-1] node.insert_child(pos, Leaf(token.INDENT, i)) node.insert_child(pos, assign_statement) node.insert_child(pos, Leaf(token.INDENT, i)) 3to2-1.1.1/lib3to2/fixes/fix_bytes.py0000666000000000000000000000256212513010502015737 0ustar rootroot""" Fixer for bytes -> str. """ import re from lib2to3 import fixer_base from lib2to3.patcomp import compile_pattern from ..fixer_util import Name, token, syms, parse_args, Call, Comma _literal_re = re.compile(r"[bB][rR]?[\'\"]") class FixBytes(fixer_base.BaseFix): order = "pre" PATTERN = "STRING | power< 'bytes' [trailer< '(' (args=arglist | any*) ')' >] > | 'bytes'" def transform(self, node, results): name = results.get("name") arglist = results.get("args") if node.type == token.NAME: return Name("str", prefix=node.prefix) elif node.type == token.STRING: if _literal_re.match(node.value): new = node.clone() new.value = new.value[1:] return new if arglist is not None: args = arglist.children parsed = parse_args(args, ("source", "encoding", "errors")) source, encoding, errors = (parsed[v] for v in ("source", "encoding", "errors")) encoding.prefix = "" str_call = Call(Name("str"), ([source.clone()])) if errors is None: node.replace(Call(Name(str(str_call) + ".encode"), (encoding.clone(),))) else: errors.prefix = " " node.replace(Call(Name(str(str_call) + ".encode"), (encoding.clone(), Comma(), errors.clone()))) 3to2-1.1.1/lib3to2/fixes/fix_bool.py0000666000000000000000000000103012513010502015531 0ustar rootroot""" Fixer for __bool__ -> __nonzero__ methods. """ from lib2to3 import fixer_base from lib2to3.fixer_util import Name class FixBool(fixer_base.BaseFix): PATTERN = """ classdef< 'class' any+ ':' suite< any* funcdef< 'def' name='__bool__' parameters< '(' NAME ')' > any+ > any* > > """ def transform(self, node, results): name = results["name"] new = Name("__nonzero__", prefix=name.prefix) name.replace(new) 3to2-1.1.1/lib3to2/fixes/fix_bitlength.py0000666000000000000000000000121712513010502016565 0ustar rootroot""" Fixer for: anything.bit_length() -> (len(bin(anything)) - 2) """ from lib2to3 import fixer_base from ..fixer_util import LParen, RParen, Call, Number, Name, Minus, Node, syms class FixBitlength(fixer_base.BaseFix): PATTERN = "power< name=any trailer< '.' 'bit_length' > trailer< '(' ')' > >" def transform(self, node, results): name = results["name"] inner = Call(Name("bin"), [Name(name.value)]) outer = Call(Name("len"), [inner]) middle = Minus(prefix=" ") two = Number("2", prefix=" ") node.replace(Node(syms.power, [LParen(), outer, middle, two, RParen()], prefix=node.prefix)) 3to2-1.1.1/lib3to2/fixes/fix_annotations.py0000666000000000000000000000305212513010502017141 0ustar rootroot""" Fixer to remove function annotations """ from lib2to3 import fixer_base from lib2to3.pgen2 import token from lib2to3.fixer_util import syms warning_text = "Removing function annotations completely." def param_without_annotations(node): return node.children[0] class FixAnnotations(fixer_base.BaseFix): warned = False def warn_once(self, node, reason): if not self.warned: self.warned = True self.warning(node, reason=reason) PATTERN = """ funcdef< 'def' any parameters< '(' [params=any] ')' > ['->' ret=any] ':' any* > """ def transform(self, node, results): """ This just strips annotations from the funcdef completely. """ params = results.get("params") ret = results.get("ret") if ret is not None: assert ret.prev_sibling.type == token.RARROW, "Invalid return annotation" self.warn_once(node, reason=warning_text) ret.prev_sibling.remove() ret.remove() if params is None: return if params.type == syms.typedargslist: # more than one param in a typedargslist for param in params.children: if param.type == syms.tname: self.warn_once(node, reason=warning_text) param.replace(param_without_annotations(param)) elif params.type == syms.tname: # one param self.warn_once(node, reason=warning_text) params.replace(param_without_annotations(params)) 3to2-1.1.1/lib3to2/fixes/fix_absimport.py0000666000000000000000000000200312513010502016577 0ustar rootroot''' Add 'from __future__ import absolute_import' to any file that uses imports. ''' from lib2to3 import fixer_base from lib2to3.pygram import python_symbols as syms from lib3to2.fixer_util import future_import class FixAbsimport(fixer_base.BaseFix): order = 'post' run_order = 10 def __init__(self, options, log): super(FixAbsimport, self).__init__(options, log) self.__abs_added = None def start_tree(self, tree, filename): super(FixAbsimport, self).start_tree(tree, filename) self.__abs_added = False def match(self, node): return (node.type in (syms.import_name, syms.import_from) and not self.__abs_added) def transform(self, node, results): try: future_import('absolute_import', node) except ValueError: pass else: self.__abs_added = True def finish_tree(self, tree, filename): fixer_base.BaseFix.finish_tree(self, tree, filename)3to2-1.1.1/lib3to2/fixes/feature_base.py0000666000000000000000000000326512513010502016371 0ustar rootroot""" Base classes for features that are backwards-incompatible. Usage: features = Features() features.add(Feature("py3k_feature", "power< 'py3k' any* >", "2.7")) PATTERN = features.PATTERN """ pattern_unformatted = "%s=%s" # name=pattern, for dict lookups message_unformatted = """ %s is only supported in Python %s and above.""" class Feature(object): """ A feature has a name, a pattern, and a minimum version of Python 2.x required to use the feature (or 3.x if there is no backwards-compatible version of 2.x) """ def __init__(self, name, PATTERN, version): self.name = name self._pattern = PATTERN self.version = version def message_text(self): """ Format the above text with the name and minimum version required. """ return message_unformatted % (self.name, self.version) class Features(set): """ A set of features that generates a pattern for the features it contains. This set will act like a mapping in that we map names to patterns. """ mapping = {} def update_mapping(self): """ Called every time we care about the mapping of names to features. """ self.mapping = dict([(f.name, f) for f in iter(self)]) @property def PATTERN(self): """ Uses the mapping of names to features to return a PATTERN suitable for using the lib2to3 patcomp. """ self.update_mapping() return " |\n".join([pattern_unformatted % (f.name, f._pattern) for f in iter(self)]) def __getitem__(self, key): """ Implement a simple mapping to get patterns from names. """ return self.mapping[key] 3to2-1.1.1/lib3to2/__init__.py0000666000000000000000000000003712513000130014353 0ustar rootroot# empty to make this a package 3to2-1.1.1/lib3to2/main.py0000666000000000000000000001507712513010502013556 0ustar rootroot# -*- coding: utf-8 -*- """ Main program for 3to2. """ from __future__ import print_function import sys import os import difflib import logging import shutil import optparse from lib2to3 import refactor from lib2to3 import pygram def diff_texts(a, b, filename): """Return a unified diff of two strings.""" a = a.splitlines() b = b.splitlines() return difflib.unified_diff(a, b, filename, filename, "(original)", "(refactored)", lineterm="") class StdoutRefactoringTool(refactor.MultiprocessRefactoringTool): """ Prints output to stdout. """ def __init__(self, fixers, options, explicit, nobackups, show_diffs): self.nobackups = nobackups self.show_diffs = show_diffs super(StdoutRefactoringTool, self).__init__(fixers, options, explicit) self.driver.grammar = pygram.python_grammar_no_print_statement def refactor_string(self, data, name): """Override to keep print statements out of the grammar""" try: tree = self.driver.parse_string(data) except Exception as err: self.log_error("Can't parse %s: %s: %s", name, err.__class__.__name__, err) return self.log_debug("Refactoring %s", name) self.refactor_tree(tree, name) return tree def log_error(self, msg, *args, **kwargs): self.errors.append((msg, args, kwargs)) self.logger.error(msg, *args, **kwargs) def write_file(self, new_text, filename, old_text, encoding): if not self.nobackups: # Make backup backup = filename + ".bak" if os.path.lexists(backup): try: os.remove(backup) except os.error as err: self.log_message("Can't remove backup %s", backup) try: os.rename(filename, backup) except os.error as err: self.log_message("Can't rename %s to %s", filename, backup) # Actually write the new file write = super(StdoutRefactoringTool, self).write_file write(new_text, filename, old_text, encoding) if not self.nobackups: shutil.copymode(backup, filename) def print_output(self, old, new, filename, equal): if equal: self.log_message("No changes to %s", filename) else: self.log_message("Refactored %s", filename) if self.show_diffs: for line in diff_texts(old, new, filename): print(line.encode('utf-8', 'ignore')) def warn(msg): print("WARNING: %s" % (msg,), file=sys.stderr) def main(fixer_pkg, args=None): """Main program. Args: fixer_pkg: the name of a package where the fixers are located. args: optional; a list of command line arguments. If omitted, sys.argv[1:] is used. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="3to2 [options] file|dir ...") parser.add_option("-d", "--doctests_only", action="store_true", help="Fix up doctests only") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; default: all") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 3to2 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations (fixes/fix_*.py)") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring") # Parse command line arguments refactor_stdin = False options, args = parser.parse_args(args) if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.list_fixes: print("Available transformations for the -f/--fix option:") for fixname in refactor.get_all_fix_names(fixer_pkg): print(fixname) if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) # Initialize the refactoring tool avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) explicit = set() if options.fix: all_present = False for fix in options.fix: if fix == "all": all_present = True else: explicit.add(fixer_pkg + ".fix_" + fix) requested = avail_fixes.union(explicit) if all_present else explicit else: requested = avail_fixes.union(explicit) fixer_names = requested.difference(unwanted_fixes) rt = StdoutRefactoringTool(sorted(fixer_names), None, sorted(explicit), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, options.doctests_only, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't supported on this platform.", file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return int(bool(rt.errors)) 3to2-1.1.1/lib3to2/fixer_util.py0000666000000000000000000001570612513010502015003 0ustar rootrootfrom lib2to3.pygram import token, python_symbols as syms from lib2to3.pytree import Leaf, Node from lib2to3.fixer_util import * def Star(prefix=None): return Leaf(token.STAR, '*', prefix=prefix) def DoubleStar(prefix=None): return Leaf(token.DOUBLESTAR, '**', prefix=prefix) def Minus(prefix=None): return Leaf(token.MINUS, '-', prefix=prefix) def commatize(leafs): """ Accepts/turns: (Name, Name, ..., Name, Name) Returns/into: (Name, Comma, Name, Comma, ..., Name, Comma, Name) """ new_leafs = [] for leaf in leafs: new_leafs.append(leaf) new_leafs.append(Comma()) del new_leafs[-1] return new_leafs def indentation(node): """ Returns the indentation for this node Iff a node is in a suite, then it has indentation. """ while node.parent is not None and node.parent.type != syms.suite: node = node.parent if node.parent is None: return "" # The first three children of a suite are NEWLINE, INDENT, (some other node) # INDENT.value contains the indentation for this suite # anything after (some other node) has the indentation as its prefix. if node.type == token.INDENT: return node.value elif node.prev_sibling is not None and node.prev_sibling.type == token.INDENT: return node.prev_sibling.value elif node.prev_sibling is None: return "" else: return node.prefix def indentation_step(node): """ Dirty little trick to get the difference between each indentation level Implemented by finding the shortest indentation string (technically, the "least" of all of the indentation strings, but tabs and spaces mixed won't get this far, so those are synonymous.) """ r = find_root(node) # Collect all indentations into one set. all_indents = set(i.value for i in r.pre_order() if i.type == token.INDENT) if not all_indents: # nothing is indented anywhere, so we get to pick what we want return " " # four spaces is a popular convention else: return min(all_indents) def suitify(parent): """ Turn the stuff after the first colon in parent's children into a suite, if it wasn't already """ for node in parent.children: if node.type == syms.suite: # already in the prefered format, do nothing return # One-liners have no suite node, we have to fake one up for i, node in enumerate(parent.children): if node.type == token.COLON: break else: raise ValueError("No class suite and no ':'!") # Move everything into a suite node suite = Node(syms.suite, [Newline(), Leaf(token.INDENT, indentation(node) + indentation_step(node))]) one_node = parent.children[i+1] one_node.remove() one_node.prefix = '' suite.append_child(one_node) parent.append_child(suite) def NameImport(package, as_name=None, prefix=None): """ Accepts a package (Name node), name to import it as (string), and optional prefix and returns a node: import [as ] """ if prefix is None: prefix = "" children = [Name("import", prefix=prefix), package] if as_name is not None: children.extend([Name("as", prefix=" "), Name(as_name, prefix=" ")]) return Node(syms.import_name, children) _compound_stmts = (syms.if_stmt, syms.while_stmt, syms.for_stmt, syms.try_stmt, syms.with_stmt) _import_stmts = (syms.import_name, syms.import_from) def import_binding_scope(node): """ Generator yields all nodes for which a node (an import_stmt) has scope The purpose of this is for a call to _find() on each of them """ # import_name / import_from are small_stmts assert node.type in _import_stmts test = node.next_sibling # A small_stmt can only be followed by a SEMI or a NEWLINE. while test.type == token.SEMI: nxt = test.next_sibling # A SEMI can only be followed by a small_stmt or a NEWLINE if nxt.type == token.NEWLINE: break else: yield nxt # A small_stmt can only be followed by either a SEMI or a NEWLINE test = nxt.next_sibling # Covered all subsequent small_stmts after the import_stmt # Now to cover all subsequent stmts after the parent simple_stmt parent = node.parent assert parent.type == syms.simple_stmt test = parent.next_sibling while test is not None: # Yes, this will yield NEWLINE and DEDENT. Deal with it. yield test test = test.next_sibling context = parent.parent # Recursively yield nodes following imports inside of a if/while/for/try/with statement if context.type in _compound_stmts: # import is in a one-liner c = context while c.next_sibling is not None: yield c.next_sibling c = c.next_sibling context = context.parent # Can't chain one-liners on one line, so that takes care of that. p = context.parent if p is None: return # in a multi-line suite while p.type in _compound_stmts: if context.type == syms.suite: yield context context = context.next_sibling if context is None: context = p.parent p = context.parent if p is None: break def ImportAsName(name, as_name, prefix=None): new_name = Name(name) new_as = Name("as", prefix=" ") new_as_name = Name(as_name, prefix=" ") new_node = Node(syms.import_as_name, [new_name, new_as, new_as_name]) if prefix is not None: new_node.prefix = prefix return new_node def future_import(feature, node): root = find_root(node) if does_tree_import("__future__", feature, node): return insert_pos = 0 for idx, node in enumerate(root.children): if node.type == syms.simple_stmt and node.children and \ node.children[0].type == token.STRING: insert_pos = idx + 1 break for thing_after in root.children[insert_pos:]: if thing_after.type == token.NEWLINE: insert_pos += 1 continue prefix = thing_after.prefix thing_after.prefix = "" break else: prefix = "" import_ = FromImport("__future__", [Leaf(token.NAME, feature, prefix=" ")]) children = [import_, Newline()] root.insert_child(insert_pos, Node(syms.simple_stmt, children, prefix=prefix)) def parse_args(arglist, scheme): """ Parse a list of arguments into a dict """ arglist = [i for i in arglist if i.type != token.COMMA] ret_mapping = dict([(k, None) for k in scheme]) for i, arg in enumerate(arglist): if arg.type == syms.argument and arg.children[1].type == token.EQUAL: # argument < NAME '=' any > slot = arg.children[0].value ret_mapping[slot] = arg.children[2] else: slot = scheme[i] ret_mapping[slot] = arg return ret_mapping 3to2-1.1.1/lib3to2/build.py0000666000000000000000000001053212513010502013720 0ustar rootroot# -*- coding: utf-8 -*- """ Created on Sun Oct 13 18:53:41 2013 @author: silvester """ import os from distutils import log from distutils.command.build_py import build_py from lib2to3 import refactor from lib2to3 import pygram class DistutilsRefactoringTool(refactor.RefactoringTool): """Refactoring tool for lib3to2 building""" def __init__(self, fixers, options=None, explicit=None): super(DistutilsRefactoringTool, self).__init__(fixers, options, explicit) self.driver.grammar = pygram.python_grammar_no_print_statement def refactor_string(self, data, name): """Override to keep print statements out of the grammar""" try: tree = self.driver.parse_string(data) except Exception, err: self.log_error("Can't parse %s: %s: %s", name, err.__class__.__name__, err) return self.log_debug("Refactoring %s", name) self.refactor_tree(tree, name) return tree def log_error(self, msg, *args, **kw): log.error(msg, *args) def log_message(self, msg, *args): log.info(msg, *args) def log_debug(self, msg, *args): log.debug(msg, *args) def run_3to2(files, fixer_names=None, options=None, explicit=None): """Invoke 3to2 on a list of Python files. The files should all come from the build area, as the modification is done in-place. To reduce the build time, only files modified since the last invocation of this function should be passed in the files argument.""" if not files: return if fixer_names is None: fixer_names = refactor.get_fixers_from_package('lib3to2.fixes') r = DistutilsRefactoringTool(fixer_names, options=options) r.refactor(files, write=True) def copydir_run_3to2(src, dest, template=None, fixer_names=None, options=None, explicit=None): """Recursively copy a directory, only copying new and changed files, running run_3to2 over all newly copied Python modules afterward. If you give a template string, it's parsed like a MANIFEST.in. """ from distutils.dir_util import mkpath from distutils.file_util import copy_file from distutils.filelist import FileList filelist = FileList() curdir = os.getcwd() os.chdir(src) try: filelist.findall() finally: os.chdir(curdir) filelist.files[:] = filelist.allfiles if template: for line in template.splitlines(): line = line.strip() if not line: continue filelist.process_template_line(line) copied = [] for filename in filelist.files: outname = os.path.join(dest, filename) mkpath(os.path.dirname(outname)) res = copy_file(os.path.join(src, filename), outname, update=1) if res[1]: copied.append(outname) run_3to2([fn for fn in copied if fn.lower().endswith('.py')], fixer_names=fixer_names, options=options, explicit=explicit) return copied class Mixin3to2: '''Mixin class for commands that run 3to2. To configure 3to2, setup scripts may either change the class variables, or inherit from individual commands to override how 3to2 is invoked.''' # provide list of fixers to run; # defaults to all from lib3to2.fixers fixer_names = None # options dictionary options = None # list of fixers to invoke even though they are marked as explicit explicit = None def run_3to2(self, files): return run_3to2(files, self.fixer_names, self.options, self.explicit) class build_py_3to2(build_py, Mixin3to2): def run(self): self.updated_files = [] # Base class code if self.py_modules: self.build_modules() if self.packages: self.build_packages() self.build_package_data() # 3to2 self.run_3to2(self.updated_files) # Remaining base class code self.byte_compile(self.get_outputs(include_bytecode=0)) def build_module(self, module, module_file, package): res = build_py.build_module(self, module, module_file, package) if res[1]: # file was copied self.updated_files.append(res[0]) return res3to2-1.1.1/setup.py0000666000000000000000000000173712513531424012525 0ustar rootroot#!/usr/bin/env python3.2 classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Topic :: Software Development :: Code Generators", "Topic :: Software Development :: Libraries :: Python Modules", ] from distutils.core import setup setup( name="3to2", packages=["lib3to2","lib3to2.fixes","lib3to2.tests"], scripts=["3to2"], version="1.1.1", url="http://www.startcodon.com/wordpress/?cat=8", author="Joe Amenta", author_email="airbreather@linux.com", classifiers=classifiers, description="Refactors valid 3.x syntax into valid 2.x syntax, if a syntactical conversion is possible", long_description="", license="", platforms="", ) 3to2-1.1.1/README0000666000000000000000000001006612513531256011671 0ustar rootrootDownload ======== Release for 2.7 and 3.x (last version I tested was 3.4.3): https://pypi.python.org/pypi/3to2 Abstract ======== lib3to2 is a set of fixers that are intended to backport code written for Python version 3.x into Python version 2.x. The final target 2.x version is the latest version of the 2.7 branch, as that is the last release in the Python 2.x branch. Some attempts have been made, however, to make code compatible as much as possible with versions of Python back to 2.5, and bug reports are still welcome for Python features only present in 2.6+ that are not addressed by lib3to2. This project came about as a Google Summer of Code (TM) project in 2009. Status ====== Because of the nature of the subject matter, 3to2 is not perfect, so check all output manually. 3to2 does the bulk of the work, but there is code that simply cannot be converted into a Python 2 equivalent for one reason or another. 3to2 will either produce working Python 2 code or warn about why it did not. Any other behavior is a bug and should be reported. lib3to2's fixers are somewhat well-tested individually, but there is no testing that is done on interactions between multiple fixers, so most of the bugs in the future will likely be found there. Intention ========= lib3to2 is intended to be a tool in the process of developing code that is backwards-compatible between Python 3 and Python 2. It is not intended to be a complete solution for directly backporting Python 3 code, though it can often be used for this purpose without issue. Sufficiently large packages should be developed with lib3to2 used throughout the process to avoid backwards- incompatible code from becoming too embedded. There are some features of Python 3 that have no equivalent in Python 2, and though lib3to2 tries to fix as many of these as it can, some features are beyond its grasp. This is especially true of features not readily detectable by their syntax alone and extremely subtle features, so make sure that code using lib3to2 is thoroughly tested. Repository ========== lib3to2 resides at http://bitbucket.org/amentajo/lib3to2, where the bug tracker can be found at http://bitbucket.org/amentajo/lib3to2/issues Usage ===== Run "./3to2" to convert stdin ("-"), files or directories given as arguments. By default, the tool outputs a unified diff-formatted patch on standard output and a "what was changed" summary on standard error, but the "-w" option can be given to write back converted files, creating ".bak"-named backup files. If you are root, you can also install with "./setup.py build" and "./setup.py install" ("make install" does this for you). This branch of 3to2 must be run with Python 3. To install locally (used for running tests as a non-privileged user), the scripts assume you are using python3.1. Modify accordingly if you are not. Relationship with lib2to3 ========================= Some of the fixers for lib3to2 are directly copy-pasted from their 2to3 equivalent, with the element of PATTERN and the corresponding transformation switched places. Most fixers written for this program with a corresponding 2to3 fixer started from a clone of the 2to3 fixer, then modifying that fixer to work in reverse. I do not claim original authorship of these fixers, but I do claim that they will work for 3to2, independent of how they work for 2to3. In addition, this program depends on lib2to3 to implement fixers, test cases, refactoring, and grammar. Some portions of lib2to3 were modified to be more generic to support lib3to2's calls. You should use the latest version of lib2to3 from the Python sandbox rather than the version (if any) that comes with Python. As a convenience, "two2three" from the Python Package Index is a recent enough version of lib2to3 renamed to avoid conflicts. To use this package, replace all usage of "lib2to3" with "two2three" within the 3to2 source files after installing "two2three" from the PyPI. Depending on the developer's mood, a version of 3to2 may be provided with this change already made.3to2-1.1.1/PKG-INFO0000666000000000000000000000160712513531540012103 0ustar rootrootMetadata-Version: 1.1 Name: 3to2 Version: 1.1.1 Summary: Refactors valid 3.x syntax into valid 2.x syntax, if a syntactical conversion is possible Home-page: http://www.startcodon.com/wordpress/?cat=8 Author: Joe Amenta Author-email: airbreather@linux.com License: UNKNOWN Description: UNKNOWN Platform: Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Topic :: Software Development :: Code Generators Classifier: Topic :: Software Development :: Libraries :: Python Modules 3to2-1.1.1/3to20000666000000000000000000000014412513000130011475 0ustar rootroot#!/usr/bin/env python3.2 import sys from lib3to2.main import main sys.exit(main("lib3to2.fixes"))