Correct flags on special methods so one can call their python functions directly.
authorRobert Bradshaw <robertwb@math.washington.edu>
Fri, 17 Aug 2007 23:11:06 +0000 (16:11 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Fri, 17 Aug 2007 23:11:06 +0000 (16:11 -0700)
Cython/Compiler/Code.py
Cython/Compiler/Symtab.py

index 87b877a20553bb25bc71c188e3d6d0d8727f2930..4cb2984f712fc069fbc7db187fd1b1229b73eeb1 100644 (file)
@@ -289,17 +289,14 @@ class CCodeWriter:
             doc_code = entry.doc_cname
         else:
             doc_code = 0
-        # Add METH_COEXIST to special methods
-        meth_flags = "METH_VARARGS|METH_KEYWORDS"
-        if get_special_method_signature(entry.name):
-            meth_flags = "METH_VARARGS|METH_KEYWORDS|METH_COEXIST"            
-        self.putln(
-            '{"%s", (PyCFunction)%s, %s, %s}%s' % (
-                entry.name, 
-                entry.func_cname,
-                meth_flags,
-                doc_code,
-                term))
+        if entry.meth_flags:
+            self.putln(
+                '{"%s", (PyCFunction)%s, %s, %s}%s' % (
+                    entry.name, 
+                    entry.func_cname,
+                    entry.meth_flags,
+                    doc_code,
+                    term))
     
     def put_error_if_neg(self, pos, value):
 #        return self.putln("if (unlikely(%s < 0)) %s" % (value, self.error_goto(pos)))  # TODO this path is almost _never_ taken, yet this macro makes is slower!
index 4aa3a7da5d8535e0ed63ba3cdfc6779f11557d84..1fadd21e3cf0bd8b8d129f52c23c958cd58c7630 100644 (file)
@@ -7,6 +7,7 @@ from Errors import error, InternalError, warning
 import Options
 import Naming
 from PyrexTypes import *
+import TypeSlots
 from TypeSlots import \
     pyfunction_signature, pymethod_signature, \
     get_special_method_signature, get_property_accessor_signature
@@ -302,6 +303,7 @@ class Scope:
         # Add an entry for a Python function.
         entry = self.declare_var(name, py_object_type, pos)
         entry.signature = pyfunction_signature
+        entry.meth_flags = "METH_VARARGS|METH_KEYWORDS"
         self.pyfunc_entries.append(entry)
         return entry
     
@@ -1088,7 +1090,14 @@ class CClassScope(ClassScope):
             # Special methods get put in the method table with a particular
             # signature declared in advance.
             entry.signature = special_sig
+            if special_sig == TypeSlots.unaryfunc:
+                entry.meth_flags = "METH_NOARGS|METH_COEXIST"
+            elif special_sig == TypeSlots.binaryfunc or special_sig == TypeSlots.ibinaryfunc:
+                entry.meth_flags = "METH_O|METH_COEXIST"
+            else:
+                entry.meth_flags = None # should it generate a wrapper function?
         else:
+            entry.meth_flags = "METH_VARARGS|METH_KEYWORDS"
             entry.signature = pymethod_signature
 
         self.pyfunc_entries.append(entry)
@@ -1172,6 +1181,7 @@ class PropertyScope(Scope):
         if signature:
             entry = self.declare(name, name, py_object_type, pos)
             entry.signature = signature
+            entry.meth_flags = None
             return entry
         else:
             error(pos, "Only __get__, __set__ and __del__ methods allowed "