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) 7a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Petersonraise E, None, T -> raise E.with_traceback(T) 85e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 95e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisraise (((E, E'), E''), E'''), V -> raise E(V) 105e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisraise "foo", V, T -> warns about string exceptions 115e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 125e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 135e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. LöwisCAVEATS: 145e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis1) "raise E, V" will be incorrectly translated if V is an exception 155e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis instance. The correct Python 3 idiom is 16ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis 175e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis raise E from V 18ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis 195e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis but since we can't detect instance-hood by syntax alone and since 205e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis any client code would have to be changed as well, we don't automate 215e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis this. 225e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis""" 235e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis# Author: Collin Winter 245e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 255e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis# Local imports 265e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisfrom .. import pytree 275e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwisfrom ..pgen2 import token 28e607823af57c176c3be23985f5bbf9260f6bd836Benjamin Petersonfrom .. import fixer_base 29e607823af57c176c3be23985f5bbf9260f6bd836Benjamin Petersonfrom ..fixer_util import Name, Call, Attr, ArgList, is_tuple 305e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 31e607823af57c176c3be23985f5bbf9260f6bd836Benjamin Petersonclass FixRaise(fixer_base.BaseFix): 325e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 33a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson BM_compatible = True 345e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis PATTERN = """ 355e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] > 365e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis """ 375e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 385e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis def transform(self, node, results): 395e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis syms = self.syms 405e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 415e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis exc = results["exc"].clone() 42a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson if exc.type == token.STRING: 43a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson msg = "Python 3 does not support string exceptions" 44a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson self.cannot_convert(node, msg) 455e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis return 465e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 475e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # Python 2 supports 485e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # raise ((((E1, E2), E3), E4), E5), V 495e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # as a synonym for 505e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # raise E1, V 515e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # Since Python 3 will not support this, we recurse down any tuple 525e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # literals, always taking the first element. 535e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis if is_tuple(exc): 54ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis while is_tuple(exc): 55ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis # exc.children[1:-1] is the unparenthesized tuple 56ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis # exc.children[1].children[0] is the first element of the tuple 57ab41b370a3eb1444b8ada38311a1bb498575a81cMartin v. Löwis exc = exc.children[1].children[0].clone() 58a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson exc.prefix = u" " 595e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 605e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis if "val" not in results: 615e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis # One-argument raise 6284ad84e0bb15e7c64109e88060afdcb60ae7b740Benjamin Peterson new = pytree.Node(syms.raise_stmt, [Name(u"raise"), exc]) 636118040b7aee905bcddcb949c6815dc19ca23070Benjamin Peterson new.prefix = node.prefix 645e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis return new 655e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 665e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis val = results["val"].clone() 675e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis if is_tuple(val): 685e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis args = [c.clone() for c in val.children[1:-1]] 695e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis else: 706118040b7aee905bcddcb949c6815dc19ca23070Benjamin Peterson val.prefix = u"" 715e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis args = [val] 725e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 735e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis if "tb" in results: 745e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis tb = results["tb"].clone() 756118040b7aee905bcddcb949c6815dc19ca23070Benjamin Peterson tb.prefix = u"" 765e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis 77a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson e = exc 78a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson # If there's a traceback and None is passed as the value, then don't 79a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson # add a call, since the user probably just wants to add a 80a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson # traceback. See issue #9661. 81a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson if val.type != token.NAME or val.value != u"None": 82a81eae1fd71eed670d1c28bf940ea99b4bfa2335Benjamin Peterson e = Call(exc, args) 8384ad84e0bb15e7c64109e88060afdcb60ae7b740Benjamin Peterson with_tb = Attr(e, Name(u'with_traceback')) + [ArgList([tb])] 8484ad84e0bb15e7c64109e88060afdcb60ae7b740Benjamin Peterson new = pytree.Node(syms.simple_stmt, [Name(u"raise")] + with_tb) 856118040b7aee905bcddcb949c6815dc19ca23070Benjamin Peterson new.prefix = node.prefix 865e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis return new 875e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis else: 885e37baea8007cb64b65a180e4d6c80de292a8a4aMartin v. Löwis return pytree.Node(syms.raise_stmt, 8984ad84e0bb15e7c64109e88060afdcb60ae7b740Benjamin Peterson [Name(u"raise"), Call(exc, args)], 906118040b7aee905bcddcb949c6815dc19ca23070Benjamin Peterson prefix=node.prefix) 91