+++ /dev/null
-"""Fixer for except statements with named exceptions.\r
-\r
-The following cases will be converted:\r
-\r
-- "except E, T:" where T is a name:\r
-\r
- except E as T:\r
-\r
-- "except E, T:" where T is not a name, tuple or list:\r
-\r
- except E as t:\r
- T = t\r
-\r
- This is done because the target of an "except" clause must be a\r
- name.\r
-\r
-- "except E, T:" where T is a tuple or list literal:\r
-\r
- except E as t:\r
- T = t.args\r
-"""\r
-# Author: Collin Winter\r
-\r
-# Local imports\r
-from .. import pytree\r
-from ..pgen2 import token\r
-from .. import fixer_base\r
-from ..fixer_util import Assign, Attr, Name, is_tuple, is_list, syms\r
-\r
-def find_excepts(nodes):\r
- for i, n in enumerate(nodes):\r
- if n.type == syms.except_clause:\r
- if n.children[0].value == u'except':\r
- yield (n, nodes[i+2])\r
-\r
-class FixExcept(fixer_base.BaseFix):\r
- BM_compatible = True\r
-\r
- PATTERN = """\r
- try_stmt< 'try' ':' (simple_stmt | suite)\r
- cleanup=(except_clause ':' (simple_stmt | suite))+\r
- tail=(['except' ':' (simple_stmt | suite)]\r
- ['else' ':' (simple_stmt | suite)]\r
- ['finally' ':' (simple_stmt | suite)]) >\r
- """\r
-\r
- def transform(self, node, results):\r
- syms = self.syms\r
-\r
- tail = [n.clone() for n in results["tail"]]\r
-\r
- try_cleanup = [ch.clone() for ch in results["cleanup"]]\r
- for except_clause, e_suite in find_excepts(try_cleanup):\r
- if len(except_clause.children) == 4:\r
- (E, comma, N) = except_clause.children[1:4]\r
- comma.replace(Name(u"as", prefix=u" "))\r
-\r
- if N.type != token.NAME:\r
- # Generate a new N for the except clause\r
- new_N = Name(self.new_name(), prefix=u" ")\r
- target = N.clone()\r
- target.prefix = u""\r
- N.replace(new_N)\r
- new_N = new_N.clone()\r
-\r
- # Insert "old_N = new_N" as the first statement in\r
- # the except body. This loop skips leading whitespace\r
- # and indents\r
- #TODO(cwinter) suite-cleanup\r
- suite_stmts = e_suite.children\r
- for i, stmt in enumerate(suite_stmts):\r
- if isinstance(stmt, pytree.Node):\r
- break\r
-\r
- # The assignment is different if old_N is a tuple or list\r
- # In that case, the assignment is old_N = new_N.args\r
- if is_tuple(N) or is_list(N):\r
- assign = Assign(target, Attr(new_N, Name(u'args')))\r
- else:\r
- assign = Assign(target, new_N)\r
-\r
- #TODO(cwinter) stopgap until children becomes a smart list\r
- for child in reversed(suite_stmts[:i]):\r
- e_suite.insert_child(0, child)\r
- e_suite.insert_child(i, assign)\r
- elif N.prefix == u"":\r
- # No space after a comma is legal; no space after "as",\r
- # not so much.\r
- N.prefix = u" "\r
-\r
- #TODO(cwinter) fix this when children becomes a smart list\r
- children = [c.clone() for c in node.children[:3]] + try_cleanup + tail\r
- return pytree.Node(node.type, children)\r