source: python/trunk/Lib/lib2to3/fixes/fix_except.py

Last change on this file was 391, checked in by dmik, 11 years ago

python: Merge vendor 2.7.6 to trunk.

  • Property svn:eol-style set to native
File size: 3.3 KB
Line 
1"""Fixer for except statements with named exceptions.
2
3The following cases will be converted:
4
5- "except E, T:" where T is a name:
6
7 except E as T:
8
9- "except E, T:" where T is not a name, tuple or list:
10
11 except E as t:
12 T = t
13
14 This is done because the target of an "except" clause must be a
15 name.
16
17- "except E, T:" where T is a tuple or list literal:
18
19 except E as t:
20 T = t.args
21"""
22# Author: Collin Winter
23
24# Local imports
25from .. import pytree
26from ..pgen2 import token
27from .. import fixer_base
28from ..fixer_util import Assign, Attr, Name, is_tuple, is_list, syms
29
30def find_excepts(nodes):
31 for i, n in enumerate(nodes):
32 if n.type == syms.except_clause:
33 if n.children[0].value == u'except':
34 yield (n, nodes[i+2])
35
36class FixExcept(fixer_base.BaseFix):
37 BM_compatible = True
38
39 PATTERN = """
40 try_stmt< 'try' ':' (simple_stmt | suite)
41 cleanup=(except_clause ':' (simple_stmt | suite))+
42 tail=(['except' ':' (simple_stmt | suite)]
43 ['else' ':' (simple_stmt | suite)]
44 ['finally' ':' (simple_stmt | suite)]) >
45 """
46
47 def transform(self, node, results):
48 syms = self.syms
49
50 tail = [n.clone() for n in results["tail"]]
51
52 try_cleanup = [ch.clone() for ch in results["cleanup"]]
53 for except_clause, e_suite in find_excepts(try_cleanup):
54 if len(except_clause.children) == 4:
55 (E, comma, N) = except_clause.children[1:4]
56 comma.replace(Name(u"as", prefix=u" "))
57
58 if N.type != token.NAME:
59 # Generate a new N for the except clause
60 new_N = Name(self.new_name(), prefix=u" ")
61 target = N.clone()
62 target.prefix = u""
63 N.replace(new_N)
64 new_N = new_N.clone()
65
66 # Insert "old_N = new_N" as the first statement in
67 # the except body. This loop skips leading whitespace
68 # and indents
69 #TODO(cwinter) suite-cleanup
70 suite_stmts = e_suite.children
71 for i, stmt in enumerate(suite_stmts):
72 if isinstance(stmt, pytree.Node):
73 break
74
75 # The assignment is different if old_N is a tuple or list
76 # In that case, the assignment is old_N = new_N.args
77 if is_tuple(N) or is_list(N):
78 assign = Assign(target, Attr(new_N, Name(u'args')))
79 else:
80 assign = Assign(target, new_N)
81
82 #TODO(cwinter) stopgap until children becomes a smart list
83 for child in reversed(suite_stmts[:i]):
84 e_suite.insert_child(0, child)
85 e_suite.insert_child(i, assign)
86 elif N.prefix == u"":
87 # No space after a comma is legal; no space after "as",
88 # not so much.
89 N.prefix = u" "
90
91 #TODO(cwinter) fix this when children becomes a smart list
92 children = [c.clone() for c in node.children[:3]] + try_cleanup + tail
93 return pytree.Node(node.type, children)
Note: See TracBrowser for help on using the repository browser.