Fix nogil function pointer assignment rules
authorGregory Ewing <greg.ewing@canterbury.ac.nz>
Sat, 24 May 2008 04:42:43 +0000 (16:42 +1200)
committerGregory Ewing <greg.ewing@canterbury.ac.nz>
Sat, 24 May 2008 04:42:43 +0000 (16:42 +1200)
Cython/Compiler/PyrexTypes.py

index 45346675092a215179fd23c50e151b90dd0b31af..062df7e27aa201622a7731dec9da9e0922f9d7de 100644 (file)
@@ -606,14 +606,18 @@ class CPtrType(CType):
     def assignable_from_resolved_type(self, other_type):
         if other_type is error_type:
             return 1
-        elif other_type.is_null_ptr:
+        if other_type.is_null_ptr:
             return 1
-        elif self.base_type.is_cfunction and other_type.is_cfunction:
-            return self.base_type.same_as(other_type)
-        elif other_type.is_array or other_type.is_ptr:
+        if self.base_type.is_cfunction:
+            if other_type.is_ptr:
+                other_type = other_type.base_type.resolve()
+            if other_type.is_cfunction:
+                return self.base_type.pointer_assignable_from_resolved_type(other_type)
+            else:
+                return 0
+        if other_type.is_array or other_type.is_ptr:
             return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
-        else:
-            return 0
+        return 0
 
 
 class CNullPtrType(CPtrType):
@@ -668,7 +672,7 @@ class CFuncType(CType):
         return self.same_c_signature_as_resolved_type(
             other_type.resolve(), as_cmethod)
 
-    def same_c_signature_as_resolved_type(self, other_type, as_cmethod):
+    def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
         #print "CFuncType.same_c_signature_as_resolved_type:", \
         #      self, other_type, "as_cmethod =", as_cmethod ###
         if other_type is error_type:
@@ -775,7 +779,13 @@ class CFuncType(CType):
     
     def same_as_resolved_type(self, other_type, as_cmethod = 0):
         return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
-            and self.same_exception_signature_as_resolved_type(other_type)
+            and self.same_exception_signature_as_resolved_type(other_type) \
+            and self.nogil == other_type.nogil
+    
+    def pointer_assignable_from_resolved_type(self, other_type):
+        return self.same_c_signature_as_resolved_type(other_type) \
+            and self.same_exception_signature_as_resolved_type(other_type) \
+            and not (self.nogil and not other_type.nogil)
     
     def declaration_code(self, entity_code, 
             for_display = 0, dll_linkage = None, pyrex = 0):
@@ -806,6 +816,8 @@ class CFuncType(CType):
         if (not entity_code and cc) or entity_code.startswith("*"):
             entity_code = "(%s%s)" % (cc, entity_code)
             cc = ""
+        if not entity_code:
+            entity_code = "()"
         return self.return_type.declaration_code(
             "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
             for_display, dll_linkage, pyrex)