1
"""Fixer for except statements with named exceptions.
3
The following cases will be converted:
5
- "except E, T:" where T is a name:
9
- "except E, T:" where T is not a name, tuple or list:
14
This is done because the target of an "except" clause must be a
17
- "except E, T:" where T is a tuple or list literal:
22
# Author: Collin Winter
26
from ..pgen2 import token
27
from .. import fixer_base
28
from ..fixer_util import Assign, Attr, Name, is_tuple, is_list
30
def find_excepts(nodes):
31
for i, n in enumerate(nodes):
32
if isinstance(n, pytree.Node):
33
if n.children[0].value == 'except':
36
class FixExcept(fixer_base.BaseFix):
39
try_stmt< 'try' ':' suite
40
cleanup=(except_clause ':' suite)+
41
tail=(['except' ':' suite]
43
['finally' ':' suite]) >
46
def transform(self, node, results):
49
tail = [n.clone() for n in results["tail"]]
51
try_cleanup = [ch.clone() for ch in results["cleanup"]]
52
for except_clause, e_suite in find_excepts(try_cleanup):
53
if len(except_clause.children) == 4:
54
(E, comma, N) = except_clause.children[1:4]
55
comma.replace(Name("as", prefix=" "))
57
if N.type != token.NAME:
58
# Generate a new N for the except clause
59
new_N = Name(self.new_name(), prefix=" ")
65
# Insert "old_N = new_N" as the first statement in
66
# the except body. This loop skips leading whitespace
68
#TODO(cwinter) suite-cleanup
69
suite_stmts = e_suite.children
70
for i, stmt in enumerate(suite_stmts):
71
if isinstance(stmt, pytree.Node):
74
# The assignment is different if old_N is a tuple or list
75
# In that case, the assignment is old_N = new_N.args
76
if is_tuple(N) or is_list(N):
77
assign = Assign(target, Attr(new_N, Name('args')))
79
assign = Assign(target, new_N)
81
#TODO(cwinter) stopgap until children becomes a smart list
82
for child in reversed(suite_stmts[:i]):
83
e_suite.insert_child(0, child)
84
e_suite.insert_child(i, assign)
85
elif N.get_prefix() == "":
86
# No space after a comma is legal; no space after "as",
90
#TODO(cwinter) fix this when children becomes a smart list
91
children = [c.clone() for c in node.children[:3]] + try_cleanup + tail
92
return pytree.Node(node.type, children)