ticket #685: implement no-arg dir()
authorStefan Behnel <scoder@users.berlios.de>
Wed, 13 Apr 2011 21:06:23 +0000 (23:06 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Wed, 13 Apr 2011 21:06:23 +0000 (23:06 +0200)
Cython/Compiler/ParseTreeTransforms.py
tests/run/locals.pyx

index 1e9cf7b12fe7c73f08897fa3ccdf9bfc58417f00..251ca7dd5ff4b0b151dd411a636694a71484b332 100644 (file)
@@ -1750,25 +1750,35 @@ class TransformBuiltinMethods(EnvTransform):
                 error(node.pos, u"'%s' not a valid cython attribute or is being used incorrectly" % attribute)
         return node
 
-    def visit_SimpleCallNode(self, node):
+    def _inject_locals(self, node, func_name):
+        # locals()/dir() builtins
+        lenv = self.current_env()
+        entry = lenv.lookup_here(func_name)
+        if entry:
+            # not the builtin
+            return node
+        max_args_count = {'dir': 1, 'locals': 0}[func_name]
+        if len(node.args) > max_args_count:
+            error(self.pos, "Builtin '%s()' called with wrong number of args, expected %d, got %d" % (
+                func_name, max_args_count, len(node.args)))
+            return node
+        pos = node.pos
+        if func_name =='locals':
+            items = [ ExprNodes.DictItemNode(pos,
+                                             key=ExprNodes.StringNode(pos, value=var),
+                                             value=ExprNodes.NameNode(pos, name=var))
+                      for var in lenv.entries ]
+            return ExprNodes.DictNode(pos, key_value_pairs=items)
+        else:
+            items = [ ExprNodes.StringNode(pos, value=var)
+                      for var in lenv.entries ]
+            return ExprNodes.ListNode(pos, args=items)
 
-        # locals builtin
+    def visit_SimpleCallNode(self, node):
         if isinstance(node.function, ExprNodes.NameNode):
-            if node.function.name == 'locals':
-                lenv = self.current_env()
-                entry = lenv.lookup_here('locals')
-                if entry:
-                    # not the builtin 'locals'
-                    return node
-                if len(node.args) > 0:
-                    error(self.pos, "Builtin 'locals()' called with wrong number of args, expected 0, got %d" % len(node.args))
-                    return node
-                pos = node.pos
-                items = [ ExprNodes.DictItemNode(pos,
-                                                 key=ExprNodes.StringNode(pos, value=var),
-                                                 value=ExprNodes.NameNode(pos, name=var))
-                          for var in lenv.entries ]
-                return ExprNodes.DictNode(pos, key_value_pairs=items)
+            func_name = node.function.name
+            if func_name in ('dir', 'locals'):
+                return self._inject_locals(node, func_name)
 
         # cython.foo
         function = node.function.as_cython_attribute()
index 6209224a29bf12f5c1a77dae710d1479b977477b..0da74c2040fa47be1b460852c54bfccd34b5b51b 100644 (file)
@@ -1,14 +1,24 @@
-__doc__ = u"""
->>> sorted( get_locals(1,2,3, k=5) .items())
-[('args', (2, 3)), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)]
-
-"""
+# mode: run
+# tag: builtins, locals, dir
 
 def get_locals(x, *args, **kwds):
+    """
+    >>> sorted( get_locals(1,2,3, k=5) .items())
+    [('args', (2, 3)), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)]
+    """
     cdef int z = 5
     y = "hi"
     return locals()
 
+def get_dir(x, *args, **kwds):
+    """
+    >>> sorted( get_dir(1,2,3, k=5) )
+    ['args', 'kwds', 'x', 'y', 'z']
+    """
+    cdef int z = 5
+    y = "hi"
+    return dir()
+
 def in_locals(x, *args, **kwds):
     """
     >>> in_locals('z')
@@ -22,6 +32,19 @@ def in_locals(x, *args, **kwds):
     y = "hi"
     return x in locals()
 
+def in_dir(x, *args, **kwds):
+    """
+    >>> in_dir('z')
+    True
+    >>> in_dir('args')
+    True
+    >>> in_dir('X')
+    False
+    """
+    cdef int z = 5
+    y = "hi"
+    return x in dir()
+
 def sorted(it):
     l = list(it)
     l.sort()