infer types of special args/kwargs parameters
authorStefan Behnel <scoder@users.berlios.de>
Sat, 5 Dec 2009 23:04:50 +0000 (00:04 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Sat, 5 Dec 2009 23:04:50 +0000 (00:04 +0100)
Cython/Compiler/Nodes.py
Cython/Compiler/TypeInference.py
tests/run/type_inference.pyx

index 403cfdc5105a4334572f7be4aadc6d0bd221f290..84ece73db7c4c5c12a3887f0270cd92faf57400d 100644 (file)
@@ -1872,8 +1872,11 @@ class DefNode(FuncDefNode):
 
     def declare_python_arg(self, env, arg):
         if arg:
-            entry = env.declare_var(arg.name, 
-                PyrexTypes.py_object_type, arg.pos)
+            if env.directives['infer_types'] != 'none':
+                type = PyrexTypes.unspecified_type
+            else:
+                type = py_object_type
+            entry = env.declare_var(arg.name, type, arg.pos)
             entry.used = 1
             entry.init = "0"
             entry.init_to_none = 0
index ff0ef3cd10fb007dabf05828bdd7e026f5bcd9f3..2e64e45f5e65a9beb30988d89450b971307d4cfa 100644 (file)
@@ -1,4 +1,6 @@
 import ExprNodes
+import Nodes
+import Builtin
 import PyrexTypes
 from PyrexTypes import py_object_type, unspecified_type, spanning_type
 from Visitor import CythonTransform
@@ -20,7 +22,7 @@ object_expr = TypedExprNode(py_object_type)
 class MarkAssignments(CythonTransform):
     
     def mark_assignment(self, lhs, rhs):
-        if isinstance(lhs, ExprNodes.NameNode):
+        if isinstance(lhs, (ExprNodes.NameNode, Nodes.PyArgDeclNode)):
             if lhs.entry is None:
                 # TODO: This shouldn't happen...
                 # It looks like comprehension loop targets are not declared soon enough.
@@ -100,6 +102,17 @@ class MarkAssignments(CythonTransform):
         self.visitchildren(node)
         return node
 
+    def visit_DefNode(self, node):
+        # use fake expressions with the right result type
+        if node.star_arg:
+            self.mark_assignment(
+                node.star_arg, TypedExprNode(Builtin.tuple_type))
+        if node.starstar_arg:
+            self.mark_assignment(
+                node.starstar_arg, TypedExprNode(Builtin.dict_type))
+        self.visitchildren(node)
+        return node
+
 
 class PyObjectTypeInferer:
     """
index ffc03cb2525df2716ab5ebfd5d190243615033b5..0cfdd5e1c1d296415adce2183379c921025d0505 100644 (file)
@@ -195,3 +195,11 @@ def safe_only():
     assert typeof(b) == "Python object", typeof(c)
     c = MyType()
     assert typeof(c) == "MyType", typeof(c)
+
+@infer_types('safe')
+def args_tuple_keywords(*args, **kwargs):
+    """
+    >>> args_tuple_keywords(1,2,3, a=1, b=2)
+    """
+    assert typeof(args) == "tuple object", typeof(args)
+    assert typeof(kwargs) == "dict object", typeof(kwargs)