Implement locals()
authorRobert Bradshaw <robertwb@math.washington.edu>
Sat, 27 Sep 2008 21:35:03 +0000 (14:35 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sat, 27 Sep 2008 21:35:03 +0000 (14:35 -0700)
Cython/Compiler/Builtin.py
Cython/Compiler/Main.py
Cython/Compiler/ParseTreeTransforms.py
tests/run/locals.pyx [new file with mode: 0644]

index d1f54162487198d1cb7c7c33ae2fec06f1c9af04..b7d3f1bf820c7d0641ff0f34f1962645b6d0e529 100644 (file)
@@ -30,6 +30,7 @@ builtin_function_table = [
     ('issubclass', "OO",   "b",     "PyObject_IsSubclass"),
     ('iter',       "O",    "O",     "PyObject_GetIter"),
     ('len',        "O",    "Z",     "PyObject_Length"),
+    ('locals',     "",     "O",     "__pyx_locals"),
     #('map',       "",     "",      ""),
     #('max',       "",     "",      ""),
     #('min',       "",     "",      ""),
index 6ed7fac626cfa9a5f63b21f3c39fbe2609938466..970fc6978f1ce01b237d7b946ca920fbc7bd6355 100644 (file)
@@ -79,7 +79,7 @@ class Context:
         from ParseTreeTransforms import WithTransform, NormalizeTree, PostParse, PxdPostParse
         from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform
         from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
-        from ParseTreeTransforms import InterpretCompilerDirectives
+        from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods
         from AutoDocTransforms import EmbedSignature
         from Optimize import FlattenInListTransform, SwitchTransform, FinalOptimizePhase
         from Buffer import IntroduceBufferAuxiliaryVars
@@ -102,6 +102,7 @@ class Context:
             WithTransform(self),
             DecoratorTransform(self),
             AnalyseDeclarationsTransform(self),
+            TransformBuiltinMethods(self),
             IntroduceBufferAuxiliaryVars(self),
             _check_c_classes,
             AnalyseExpressionsTransform(self),
index 4d05361fab332853b8485f2203301df3c008fba1..825265d54ceed34db57ebaca9915a77c383923ca 100644 (file)
@@ -534,6 +534,7 @@ property NAME:
         return property
 
 class AnalyseExpressionsTransform(CythonTransform):
+
     def visit_ModuleNode(self, node):
         node.body.analyse_expressions(node.scope)
         self.visitchildren(node)
@@ -591,3 +592,31 @@ class CreateClosureClasses(CythonTransform):
         return node
         
 
+class EnvTransform(CythonTransform):
+    """
+    This transformation keeps a stack of the environments. 
+    """
+    def __call__(self, root):
+        self.env_stack = [root.scope]
+        return super(EnvTransform, self).__call__(root)        
+    
+    def visit_FuncDefNode(self, node):
+        self.env_stack.append(node.local_scope)
+        self.visitchildren(node)
+        self.env_stack.pop()
+        return node
+
+
+class TransformBuiltinMethods(EnvTransform):
+
+    def visit_SimpleCallNode(self, node):
+        self.visitchildren(node)
+        if isinstance(node.function, ExprNodes.NameNode):
+            if node.function.name == 'locals':
+                pos = node.pos
+                lenv = self.env_stack[-1]
+                items = [ExprNodes.DictItemNode(pos, 
+                                                key=ExprNodes.IdentifierStringNode(pos, value=var),
+                                                value=ExprNodes.NameNode(pos, name=var)) for var in lenv.entries]
+                return ExprNodes.DictNode(pos, key_value_pairs=items)
+        return node
diff --git a/tests/run/locals.pyx b/tests/run/locals.pyx
new file mode 100644 (file)
index 0000000..c25480a
--- /dev/null
@@ -0,0 +1,9 @@
+__doc__ = """
+sage: get_locals(1,2,3)
+{'args': (2, 3), 'kwds': {}, 'x': 1, 'y': 'hi', 'z': 5}
+"""
+
+def get_locals(x, *args, **kwds):
+    y = "hi"
+    cdef int z = 5
+    return locals()