Commit 61372024 authored by Robert Bradshaw's avatar Robert Bradshaw

Fix cpdef functions with pointer return parameters, make cpdef functions coercable into objects.

parent 2225853e
...@@ -1801,6 +1801,19 @@ class AttributeNode(ExprNode): ...@@ -1801,6 +1801,19 @@ class AttributeNode(ExprNode):
entry = None entry = None
is_called = 0 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): def compile_time_value(self, denv):
attr = self.attribute attr = self.attribute
if attr.beginswith("__") and attr.endswith("__"): if attr.beginswith("__") and attr.endswith("__"):
...@@ -1953,6 +1966,11 @@ class AttributeNode(ExprNode): ...@@ -1953,6 +1966,11 @@ class AttributeNode(ExprNode):
# type, or it is an extension type and the attribute is either not # 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 # declared or is declared as a Python method. Treat it as a Python
# attribute reference. # 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: if obj_type.is_pyobject:
self.type = py_object_type self.type = py_object_type
self.is_py_attr = 1 self.is_py_attr = 1
......
...@@ -1010,8 +1010,8 @@ class CFuncDefNode(FuncDefNode): ...@@ -1010,8 +1010,8 @@ class CFuncDefNode(FuncDefNode):
import ExprNodes import ExprNodes
py_func_body = self.call_self_node(is_module_scope = env.is_module_scope) py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
self.py_func = DefNode(pos = self.pos, self.py_func = DefNode(pos = self.pos,
name = self.declarator.base.name, name = self.entry.name,
args = self.declarator.args, args = self.args,
star_arg = None, star_arg = None,
starstar_arg = None, starstar_arg = None,
doc = self.doc, doc = self.doc,
...@@ -1035,10 +1035,10 @@ class CFuncDefNode(FuncDefNode): ...@@ -1035,10 +1035,10 @@ class CFuncDefNode(FuncDefNode):
args = args[:len(args) - self.type.optional_arg_count] args = args[:len(args) - self.type.optional_arg_count]
arg_names = [arg.name for arg in args] arg_names = [arg.name for arg in args]
if is_module_scope: if is_module_scope:
cfunc = ExprNodes.NameNode(self.pos, name=self.declarator.base.name) cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
else: else:
self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0]) 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 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) 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) return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment