Fix cpdef functions with pointer return parameters, make cpdef functions coercable...
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 30 Mar 2008 09:18:18 +0000 (02:18 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 30 Mar 2008 09:18:18 +0000 (02:18 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py

index 63be9d6168862ff7768f0301c94e168b5cf53ca6..8515688cf0535d5660b5471c81f448025ec26ab5 100644 (file)
@@ -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
index d1a93ab2f334d99e0c8bee8398426f3f2a66a5f3..1a3cca71a41d2169d422978d9309e4889345abe7 100644 (file)
@@ -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)