fix_raise.py revision ab41b370a3eb1444b8ada38311a1bb498575a81c
15e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis"""Fixer for 'raise E, V, T' 25e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 35e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisraise -> raise 45e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisraise E -> raise E 55e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisraise E, V -> raise E(V) 65e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisraise E, V, T -> raise E(V).with_traceback(T) 75e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 85e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisraise (((E, E'), E''), E'''), V -> raise E(V) 95e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisraise "foo", V, T -> warns about string exceptions 105e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 115e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 125e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. LöwisCAVEATS: 135e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis1) "raise E, V" will be incorrectly translated if V is an exception 145e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis instance. The correct Python 3 idiom is 15ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis 165e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis raise E from V 17ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis 185e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis but since we can't detect instance-hood by syntax alone and since 195e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis any client code would have to be changed as well, we don't automate 205e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis this. 215e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis""" 225e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis# Author: Collin Winter 235e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 245e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis# Local imports 255e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisfrom .. import pytree 265e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisfrom ..pgen2 import token 275e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisfrom .import basefix 285e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisfrom .util import Name, Call, Attr, ArgList, is_tuple 295e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 305e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisclass FixRaise(basefix.BaseFix): 315e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 325e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis PATTERN = """ 335e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] > 345e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis """ 355e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 365e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis def transform(self, node, results): 375e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis syms = self.syms 385e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 395e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis exc = results["exc"].clone() 405e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis if exc.type is token.STRING: 415e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis self.cannot_convert(node, "Python 3 does not support string exceptions") 425e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis return 435e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 445e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # Python 2 supports 455e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # raise ((((E1, E2), E3), E4), E5), V 465e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # as a synonym for 475e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # raise E1, V 485e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # Since Python 3 will not support this, we recurse down any tuple 495e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # literals, always taking the first element. 505e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis if is_tuple(exc): 51ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis while is_tuple(exc): 52ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis # exc.children[1:-1] is the unparenthesized tuple 53ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis # exc.children[1].children[0] is the first element of the tuple 54ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis exc = exc.children[1].children[0].clone() 55ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis exc.set_prefix(" ") 565e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 575e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis if "val" not in results: 585e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # One-argument raise 595e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis new = pytree.Node(syms.raise_stmt, [Name("raise"), exc]) 605e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis new.set_prefix(node.get_prefix()) 615e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis return new 625e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 635e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis val = results["val"].clone() 645e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis if is_tuple(val): 655e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis args = [c.clone() for c in val.children[1:-1]] 665e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis else: 675e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis val.set_prefix("") 685e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis args = [val] 695e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 705e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis if "tb" in results: 715e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis tb = results["tb"].clone() 725e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis tb.set_prefix("") 735e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 745e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis e = Call(exc, args) 755e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] 765e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis new = pytree.Node(syms.simple_stmt, [Name("raise")] + with_tb) 775e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis new.set_prefix(node.get_prefix()) 785e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis return new 795e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis else: 805e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis return pytree.Node(syms.raise_stmt, 815e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis [Name("raise"), Call(exc, args)], 825e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis prefix=node.get_prefix()) 83