diff --git a/Lib/lib2to3/fixer_util.py b/Lib/lib2to3/fixer_util.py index 2b1cea5843e..4b5ca349eb1 100644 --- a/Lib/lib2to3/fixer_util.py +++ b/Lib/lib2to3/fixer_util.py @@ -51,12 +51,12 @@ def Dot(): def ArgList(args, lparen=LParen(), rparen=RParen()): """A parenthesised argument list, used by Call()""" - return Node(syms.trailer, - [lparen.clone(), - Node(syms.arglist, args), - rparen.clone()]) + node = Node(syms.trailer, [lparen.clone(), rparen.clone()]) + if args: + node.insert_child(1, Node(syms.arglist, args)) + return node -def Call(func_name, args, prefix=None): +def Call(func_name, args=None, prefix=None): """A function call""" node = Node(syms.power, [func_name, ArgList(args)]) if prefix is not None: diff --git a/Lib/lib2to3/fixes/fix_paren.py b/Lib/lib2to3/fixes/fix_paren.py new file mode 100644 index 00000000000..0b72bb157cf --- /dev/null +++ b/Lib/lib2to3/fixes/fix_paren.py @@ -0,0 +1,42 @@ +"""Fixer that addes parentheses where they are required + +This converts ``[x for x in 1, 2]`` to ``[x for x in (1, 2)]``.""" + +# By Taek Joo Kim and Benjamin Peterson + +# Local imports +from .. import fixer_base +from ..fixer_util import LParen, RParen + +# XXX This doesn't support nested for loops like [x for x in 1, 2 for x in 1, 2] +class FixParen(fixer_base.BaseFix): + PATTERN = """ + atom< ('[' | '(') + (listmaker< any + comp_for< + 'for' NAME 'in' + target=testlist_safe< any (',' any)+ [','] + > + [any] + > + > + | + testlist_gexp< any + comp_for< + 'for' NAME 'in' + target=testlist_safe< any (',' any)+ [','] + > + [any] + > + >) + (']' | ')') > + """ + + def transform(self, node, results): + target = results["target"] + + lparen = LParen() + lparen.set_prefix(target.get_prefix()) + target.set_prefix("") # Make it hug the parentheses + target.insert_child(0, lparen) + target.append_child(RParen()) diff --git a/Lib/lib2to3/fixes/fix_raw_input.py b/Lib/lib2to3/fixes/fix_raw_input.py index d9130d01245..53e7a32fb66 100644 --- a/Lib/lib2to3/fixes/fix_raw_input.py +++ b/Lib/lib2to3/fixes/fix_raw_input.py @@ -8,7 +8,7 @@ from ..fixer_util import Name class FixRawInput(fixer_base.BaseFix): PATTERN = """ - power< name='raw_input' trailer< '(' [any] ')' > > + power< name='raw_input' trailer< '(' [any] ')' > any* > """ def transform(self, node, results): diff --git a/Lib/lib2to3/fixes/fix_sys_exc.py b/Lib/lib2to3/fixes/fix_sys_exc.py new file mode 100644 index 00000000000..18d93635b92 --- /dev/null +++ b/Lib/lib2to3/fixes/fix_sys_exc.py @@ -0,0 +1,29 @@ +"""Fixer for sys.exc_{type, value, traceback} + +sys.exc_type -> sys.exc_info()[0] +sys.exc_value -> sys.exc_info()[1] +sys.exc_traceback -> sys.exc_info()[2] +""" + +# By Jeff Balogh and Benjamin Peterson + +# Local imports +from .. import fixer_base +from ..fixer_util import Attr, Call, Name, Number, Subscript, Node, syms + +class FixSysExc(fixer_base.BaseFix): + # This order matches the ordering of sys.exc_info(). + exc_info = ["exc_type", "exc_value", "exc_traceback"] + PATTERN = """ + power< 'sys' trailer< dot='.' attribute=(%s) > > + """ % '|'.join("'%s'" % e for e in exc_info) + + def transform(self, node, results): + sys_attr = results["attribute"][0] + index = Number(self.exc_info.index(sys_attr.value)) + + call = Call(Name("exc_info"), prefix=sys_attr.get_prefix()) + attr = Attr(Name("sys"), call) + attr[1].children[0].set_prefix(results["dot"].get_prefix()) + attr.append(Subscript(index)) + return Node(syms.power, attr, prefix=node.get_prefix()) diff --git a/Lib/lib2to3/refactor.py b/Lib/lib2to3/refactor.py index 3e93da63238..f524351e656 100755 --- a/Lib/lib2to3/refactor.py +++ b/Lib/lib2to3/refactor.py @@ -69,13 +69,7 @@ def main(fixer_dir, args=None): return 2 # Set up logging handler - if sys.version_info < (2, 4): - hdlr = logging.StreamHandler() - fmt = logging.Formatter('%(name)s: %(message)s') - hdlr.setFormatter(fmt) - logging.root.addHandler(hdlr) - else: - logging.basicConfig(format='%(name)s: %(message)s', level=logging.INFO) + logging.basicConfig(format='%(name)s: %(message)s', level=logging.INFO) # Initialize the refactoring tool rt = RefactoringTool(fixer_dir, options) diff --git a/Lib/lib2to3/tests/test_fixers.py b/Lib/lib2to3/tests/test_fixers.py index dce6f608a26..ecc7f0259cb 100755 --- a/Lib/lib2to3/tests/test_fixers.py +++ b/Lib/lib2to3/tests/test_fixers.py @@ -1340,6 +1340,21 @@ class Test_raw_input(FixerTestCase): a = """x = input(foo(a) + 6)""" self.check(b, a) + def test_5(self): + b = """x = raw_input(invite).split()""" + a = """x = input(invite).split()""" + self.check(b, a) + + def test_6(self): + b = """x = raw_input(invite) . split ()""" + a = """x = input(invite) . split ()""" + self.check(b, a) + + def test_8(self): + b = "x = int(raw_input())" + a = "x = int(input())" + self.check(b, a) + class Test_funcattrs(FixerTestCase): fixer = "funcattrs" @@ -3330,6 +3345,98 @@ class Test_import(FixerTestCase): """ self.check_both(b, a) +class Test_sys_exc(FixerTestCase): + fixer = "sys_exc" + + def test_0(self): + b = "sys.exc_type" + a = "sys.exc_info()[0]" + self.check(b, a) + + def test_1(self): + b = "sys.exc_value" + a = "sys.exc_info()[1]" + self.check(b, a) + + def test_2(self): + b = "sys.exc_traceback" + a = "sys.exc_info()[2]" + self.check(b, a) + + def test_3(self): + b = "sys.exc_type # Foo" + a = "sys.exc_info()[0] # Foo" + self.check(b, a) + + def test_4(self): + b = "sys. exc_type" + a = "sys. exc_info()[0]" + self.check(b, a) + + def test_5(self): + b = "sys .exc_type" + a = "sys .exc_info()[0]" + self.check(b, a) + + +class Test_paren(FixerTestCase): + fixer = "paren" + + def test_0(self): + b = """[i for i in 1, 2 ]""" + a = """[i for i in (1, 2) ]""" + self.check(b, a) + + def test_1(self): + b = """[i for i in 1, 2, ]""" + a = """[i for i in (1, 2,) ]""" + self.check(b, a) + + def test_2(self): + b = """[i for i in 1, 2 ]""" + a = """[i for i in (1, 2) ]""" + self.check(b, a) + + def test_3(self): + b = """[i for i in 1, 2 if i]""" + a = """[i for i in (1, 2) if i]""" + self.check(b, a) + + def test_4(self): + b = """[i for i in 1, 2 ]""" + a = """[i for i in (1, 2) ]""" + self.check(b, a) + + def test_5(self): + b = """(i for i in 1, 2)""" + a = """(i for i in (1, 2))""" + self.check(b, a) + + def test_6(self): + b = """(i for i in 1 ,2 if i)""" + a = """(i for i in (1 ,2) if i)""" + self.check(b, a) + + def test_unchanged_0(self): + s = """[i for i in (1, 2)]""" + self.unchanged(s) + + def test_unchanged_1(self): + s = """[i for i in foo()]""" + self.unchanged(s) + + def test_unchanged_2(self): + s = """[i for i in (1, 2) if nothing]""" + self.unchanged(s) + + def test_unchanged_3(self): + s = """(i for i in (1, 2))""" + self.unchanged(s) + + def test_unchanged_4(self): + s = """[i for i in m]""" + self.unchanged(s) + if __name__ == "__main__": import __main__