From 613720247b534fbe8fef2352f81349245387f0ad Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Sun, 30 Mar 2008 02:18:18 -0700 Subject: [PATCH] Fix cpdef functions with pointer return parameters, make cpdef functions coercable into objects. --- Cython/Compiler/ExprNodes.py | 18 ++++++++++++++++++ Cython/Compiler/Nodes.py | 8 ++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 63be9d61..8515688c 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1801,6 +1801,19 @@ class AttributeNode(ExprNode): entry = None is_called = 0 + def coerce_to(self, dst_type, env): + # If coercing to a generic pyobject and this is a cpdef function + # we can create the corresponding attribute + if dst_type is py_object_type: + entry = self.entry + if entry and entry.is_cfunction and entry.as_variable: + # must be a cpdef function + self.is_temp = 1 + self.entry = entry.as_variable + self.analyse_as_python_attribute(env) + return self + return AtomicExprNode.coerce_to(self, dst_type, env) + def compile_time_value(self, denv): attr = self.attribute if attr.beginswith("__") and attr.endswith("__"): @@ -1953,6 +1966,11 @@ class AttributeNode(ExprNode): # type, or it is an extension type and the attribute is either not # declared or is declared as a Python method. Treat it as a Python # attribute reference. + self.analyse_as_python_attribute(env) + + def analyse_as_python_attribute(self, env): + obj_type = self.obj.type + self.member = self.attribute if obj_type.is_pyobject: self.type = py_object_type self.is_py_attr = 1 diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index d1a93ab2..1a3cca71 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1010,8 +1010,8 @@ class CFuncDefNode(FuncDefNode): import ExprNodes py_func_body = self.call_self_node(is_module_scope = env.is_module_scope) self.py_func = DefNode(pos = self.pos, - name = self.declarator.base.name, - args = self.declarator.args, + name = self.entry.name, + args = self.args, star_arg = None, starstar_arg = None, doc = self.doc, @@ -1035,10 +1035,10 @@ class CFuncDefNode(FuncDefNode): args = args[:len(args) - self.type.optional_arg_count] arg_names = [arg.name for arg in args] if is_module_scope: - cfunc = ExprNodes.NameNode(self.pos, name=self.declarator.base.name) + cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name) else: self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0]) - cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.declarator.base.name) + cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name) skip_dispatch = not is_module_scope or Options.lookup_module_cpdef c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1-is_module_scope:]], wrapper_call=skip_dispatch) return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call) -- 2.26.2