OLD | NEW |
(Empty) | |
| 1 u""" |
| 2 Fixer for (metaclass=X) -> __metaclass__ = X |
| 3 Some semantics (see PEP 3115) may be altered in the translation.""" |
| 4 |
| 5 from lib2to3 import fixer_base |
| 6 from lib2to3.fixer_util import Name, syms, Node, Leaf, Newline, find_root |
| 7 from lib2to3.pygram import token |
| 8 from libfuturize.fixer_util import indentation, suitify |
| 9 # from ..fixer_util import Name, syms, Node, Leaf, Newline, find_root, indentati
on, suitify |
| 10 |
| 11 def has_metaclass(parent): |
| 12 results = None |
| 13 for node in parent.children: |
| 14 kids = node.children |
| 15 if node.type == syms.argument: |
| 16 if kids[0] == Leaf(token.NAME, u"metaclass") and \ |
| 17 kids[1] == Leaf(token.EQUAL, u"=") and \ |
| 18 kids[2]: |
| 19 #Hack to avoid "class X(=):" with this case. |
| 20 results = [node] + kids |
| 21 break |
| 22 elif node.type == syms.arglist: |
| 23 # Argument list... loop through it looking for: |
| 24 # Node(*, [*, Leaf(token.NAME, u"metaclass"), Leaf(token.EQUAL, u"="
), Leaf(*, *)] |
| 25 for child in node.children: |
| 26 if results: break |
| 27 if child.type == token.COMMA: |
| 28 #Store the last comma, which precedes the metaclass |
| 29 comma = child |
| 30 elif type(child) == Node: |
| 31 meta = equal = name = None |
| 32 for arg in child.children: |
| 33 if arg == Leaf(token.NAME, u"metaclass"): |
| 34 #We have the (metaclass) part |
| 35 meta = arg |
| 36 elif meta and arg == Leaf(token.EQUAL, u"="): |
| 37 #We have the (metaclass=) part |
| 38 equal = arg |
| 39 elif meta and equal: |
| 40 #Here we go, we have (metaclass=X) |
| 41 name = arg |
| 42 results = (comma, meta, equal, name) |
| 43 break |
| 44 return results |
| 45 |
| 46 |
| 47 class FixMetaclass(fixer_base.BaseFix): |
| 48 |
| 49 PATTERN = u""" |
| 50 classdef<any*> |
| 51 """ |
| 52 |
| 53 def transform(self, node, results): |
| 54 meta_results = has_metaclass(node) |
| 55 if not meta_results: return |
| 56 for meta in meta_results: |
| 57 meta.remove() |
| 58 target = Leaf(token.NAME, u"__metaclass__") |
| 59 equal = Leaf(token.EQUAL, u"=", prefix=u" ") |
| 60 # meta is the last item in what was returned by has_metaclass(): name |
| 61 name = meta |
| 62 name.prefix = u" " |
| 63 stmt_node = Node(syms.atom, [target, equal, name]) |
| 64 |
| 65 suitify(node) |
| 66 for item in node.children: |
| 67 if item.type == syms.suite: |
| 68 for stmt in item.children: |
| 69 if stmt.type == token.INDENT: |
| 70 # Insert, in reverse order, the statement, a newline, |
| 71 # and an indent right after the first indented line |
| 72 loc = item.children.index(stmt) + 1 |
| 73 # Keep consistent indentation form |
| 74 ident = Leaf(token.INDENT, stmt.value) |
| 75 item.insert_child(loc, ident) |
| 76 item.insert_child(loc, Newline()) |
| 77 item.insert_child(loc, stmt_node) |
| 78 break |
OLD | NEW |