| u""" |
| Fixer for (metaclass=X) -> __metaclass__ = X |
| Some semantics (see PEP 3115) may be altered in the translation.""" |
|
|
| from lib2to3 import fixer_base |
| from lib2to3.fixer_util import Name, syms, Node, Leaf, Newline, find_root |
| from lib2to3.pygram import token |
| from libfuturize.fixer_util import indentation, suitify |
| |
|
|
| def has_metaclass(parent): |
| results = None |
| for node in parent.children: |
| kids = node.children |
| if node.type == syms.argument: |
| if kids[0] == Leaf(token.NAME, u"metaclass") and \ |
| kids[1] == Leaf(token.EQUAL, u"=") and \ |
| kids[2]: |
| |
| results = [node] + kids |
| break |
| elif node.type == syms.arglist: |
| |
| |
| for child in node.children: |
| if results: break |
| if child.type == token.COMMA: |
| |
| comma = child |
| elif type(child) == Node: |
| meta = equal = name = None |
| for arg in child.children: |
| if arg == Leaf(token.NAME, u"metaclass"): |
| |
| meta = arg |
| elif meta and arg == Leaf(token.EQUAL, u"="): |
| |
| equal = arg |
| elif meta and equal: |
| |
| name = arg |
| results = (comma, meta, equal, name) |
| break |
| return results |
|
|
|
|
| class FixMetaclass(fixer_base.BaseFix): |
|
|
| PATTERN = u""" |
| classdef<any*> |
| """ |
|
|
| def transform(self, node, results): |
| meta_results = has_metaclass(node) |
| if not meta_results: return |
| for meta in meta_results: |
| meta.remove() |
| target = Leaf(token.NAME, u"__metaclass__") |
| equal = Leaf(token.EQUAL, u"=", prefix=u" ") |
| |
| name = meta |
| name.prefix = u" " |
| stmt_node = Node(syms.atom, [target, equal, name]) |
|
|
| suitify(node) |
| for item in node.children: |
| if item.type == syms.suite: |
| for stmt in item.children: |
| if stmt.type == token.INDENT: |
| |
| |
| loc = item.children.index(stmt) + 1 |
| |
| ident = Leaf(token.INDENT, stmt.value) |
| item.insert_child(loc, ident) |
| item.insert_child(loc, Newline()) |
| item.insert_child(loc, stmt_node) |
| break |
|
|