add <locals> to __qualname__ for closures as defined by PEP 3155
authorStefan Behnel <stefan_ml@behnel.de>
Sun, 6 Jan 2013 13:00:39 +0000 (14:00 +0100)
committerStefan Behnel <stefan_ml@behnel.de>
Sun, 6 Jan 2013 13:00:39 +0000 (14:00 +0100)
Cython/Compiler/ExprNodes.py
tests/run/cyfunction.pyx

index 3c4d865..d3f968b 100755 (executable)
@@ -6019,10 +6019,13 @@ class DictItemNode(ExprNode):
 class ModuleNameMixin(object):
     def set_qualified_name(self, env, self_name):
         self.module_name = env.global_scope().qualified_name
-        prefix = env.qualified_name[len(self.module_name)+1:]
-        if prefix:
-            self_name = prefix + '.' + self_name
-        self.qualname = StringEncoding.EncodedString(self_name)
+        qualified_name = [self_name]
+        while env and not env.is_module_scope:
+            if env.is_closure_scope:
+                qualified_name.append('<locals>')
+            qualified_name.append(env.name)
+            env = env.parent_scope
+        self.qualname = StringEncoding.EncodedString('.'.join(qualified_name[::-1]))
 
     def get_py_mod_name(self, code):
         return code.get_py_string_const(
index 2c3e024..3c19d21 100644 (file)
@@ -47,20 +47,24 @@ def test_qualname():
 
 def test_nested_qualname():
     """
-    >>> func = test_nested_qualname()
+    >>> func, lambda_func = test_nested_qualname()
+
     >>> func().__qualname__
-    'test_nested_qualname.outer.Test'
+    'test_nested_qualname.<locals>.outer.<locals>.Test'
     >>> func().test.__qualname__
-    'test_nested_qualname.outer.Test.test'
+    'test_nested_qualname.<locals>.outer.<locals>.Test.test'
     >>> func()().test.__qualname__
-    'test_nested_qualname.outer.Test.test'
+    'test_nested_qualname.<locals>.outer.<locals>.Test.test'
+
+    >>> lambda_func.__qualname__
+    'test_nested_qualname.<locals>.<lambda>'
     """
     def outer():
         class Test(object):
             def test(self):
                 return 123
         return Test
-    return outer
+    return outer, lambda:None
 
 
 def test_doc():