joe.amenta  committed e91eae4

fix_metaclass now removes the original (metaclass=X) from the classdef; still unfinished.

Comments (0)

Files changed (2)

File lib3to2/fixes/fix_metaclass.py Modified

View file
  • Ignore whitespace
  • Hide word diff
     PATTERN = """
     classdef<any*>
     """
-    
+    arg_num = 0
     def transform(self, node, results):
-        meta = self.has_metaclass(node)
-        if not meta: return
-        meta.remove()
+        meta_results = self.has_metaclass(node)
+        if not meta_results: return
+        for meta in meta_results:
+            print meta
+            meta.remove()
         target = Leaf(token.NAME, u"__metaclass__")
         equal = Leaf(token.EQUAL, u"=", prefix=u" ")
-        meta.prefix = u" "
-        stmt_node = Node(syms.atom, [target, equal, meta])
+        #meta is the last item in what was returned by has_metaclass(): name
+        name = meta
+        name.prefix = u" "
+        stmt_node = Node(syms.atom, [target, equal, name])
         
     def has_metaclass(self, parent):
-        name = None
+        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]:
-                #One argument, it's the (metaclass=X) part...
-                    name = kids[2]
+                    #Hack to avoid "class X(=):" with this case.
+                    results = [node] + kids
+                    break
             elif node.type == syms.arglist:
                 #Argument list... loop through it looking for:
                 #Node(*, [*, Leaf(token.NAME, u"metaclass"), Leaf(token.EQUAL, u"="), Leaf(*, *)]
                 for child in node.children:
-                    if type(child) == Node:
-                        meta = equal = None
+                    if results: break
+                    if type(child) == Leaf:
+                        if child.type == token.COMMA:
+                            #Store the last comma, which precedes the metaclass
+                            comma = child
+                    elif type(child) == Node:
+                        meta = equal = name = None
                         for arg in child.children:
                             if arg == Leaf(token.NAME, u"metaclass"):
                                 #We have the (metaclass) part
                             elif meta and equal:
                                 #Here we go, we have (metaclass=X)
                                 name = arg
-                            elif name:
-                                raise SyntaxError("Argument after metaclass=X")
-        return name
+                                results = (comma, meta, equal, name)
+                                break
+        return results

File lib3to2/tests/test_metaclass.py Modified

View file
  • Ignore whitespace
  • Hide word diff
         self.unchanged("class X(object1, object2, object3): pass")
 
         s = """
-        class X:
+        class X():
             def __metaclass__(self): pass
         """
         self.unchanged(s)
 
         s = """
-        class X:
+        class X():
             a[23] = 74
         """
         self.unchanged(s)
 
     def test_comments(self):
         a = """
-        class X:
+        class X():
             # hi
             __metaclass__ = AppleMeta
         """
         self.check(b, a)
 
         a = """
-        class X:
+        class X():
             __metaclass__ = Meta
             # Bedtime!
         """
 
     def test_meta_oneparent_simple_body_2(self):
         a = """
-        class X:
+        class X():
             __metaclass__ = Meta; x = 4; g = 23
         """
         b = """
     def test_meta_noparent_simple_body(self):
     
         a = """
-        class X:
+        class X():
             __metaclass__ = Meta
             save.py = 23
         """