From d8cc99c75c90af5f11580f06422e0fd374a8d58a Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sun, 6 Dec 2009 00:04:50 +0100 Subject: [PATCH] infer types of special args/kwargs parameters --- Cython/Compiler/Nodes.py | 7 +++++-- Cython/Compiler/TypeInference.py | 15 ++++++++++++++- tests/run/type_inference.pyx | 8 ++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 403cfdc5..84ece73d 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -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 diff --git a/Cython/Compiler/TypeInference.py b/Cython/Compiler/TypeInference.py index ff0ef3cd..2e64e45f 100644 --- a/Cython/Compiler/TypeInference.py +++ b/Cython/Compiler/TypeInference.py @@ -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: """ diff --git a/tests/run/type_inference.pyx b/tests/run/type_inference.pyx index ffc03cb2..0cfdd5e1 100644 --- a/tests/run/type_inference.pyx +++ b/tests/run/type_inference.pyx @@ -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) -- 2.26.2