Avoid call to PyArg_ParseTupleAndKeywords for zero- and single-argument functions.
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 19 Aug 2007 02:44:28 +0000 (19:44 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 19 Aug 2007 02:44:28 +0000 (19:44 -0700)
Cython/Compiler/Code.py
Cython/Compiler/Nodes.py
Cython/Compiler/Symtab.py
Cython/Compiler/TypeSlots.py

index 4cb2984f712fc069fbc7db187fd1b1229b73eeb1..14fbe2a4f7a6be6e0a0c831341ce971bb37c550d 100644 (file)
@@ -294,7 +294,7 @@ class CCodeWriter:
                 '{"%s", (PyCFunction)%s, %s, %s}%s' % (
                     entry.name, 
                     entry.func_cname,
-                    entry.meth_flags,
+                    "|".join(entry.meth_flags),
                     doc_code,
                     term))
     
index c7329d5781e5160ce224bcd37a3f0ef23f967e67..4bf256b9ee226d1310107fed8bb328aae02926f4 100644 (file)
@@ -8,6 +8,7 @@ import Code
 from Errors import error, warning, InternalError
 import Naming
 import PyrexTypes
+import TypeSlots
 from PyrexTypes import py_object_type, error_type, CTypedefType
 from Symtab import ModuleScope, LocalScope, \
     StructOrUnionScope, PyClassScope, CClassScope
@@ -819,6 +820,13 @@ class DefNode(FuncDefNode):
     
     def analyse_signature(self, env):
         any_type_tests_needed = 0
+        if self.entry.signature is TypeSlots.pymethod_signature:
+            if len(self.args) == 1:
+                self.entry.signature = TypeSlots.unaryfunc
+                self.entry.meth_flags = [TypeSlots.method_noargs]
+            elif len(self.args) == 2 and self.args[1].type.is_pyobject and self.args[1].default is None:
+                self.entry.signature = TypeSlots.ibinaryfunc
+                self.entry.meth_flags = [TypeSlots.method_onearg]
         sig = self.entry.signature
         nfixed = sig.num_fixed_args()
         for i in range(nfixed):
@@ -963,6 +971,8 @@ class DefNode(FuncDefNode):
                 else:
                     arg_code_list.append(
                         arg.hdr_type.declaration_code(arg.hdr_cname))
+        if self.entry.meth_flags == [TypeSlots.method_noargs]:
+            arg_code_list.append("PyObject *unused")
         if sig.has_generic_args:
             arg_code_list.append(
                 "PyObject *%s, PyObject *%s"
index 1fadd21e3cf0bd8b8d129f52c23c958cd58c7630..88e7af5b18a775c3eaebc961125434a11d4dccfa 100644 (file)
@@ -303,7 +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"
+        entry.meth_flags = [TypeSlots.method_varargs, TypeSlots.method_keywords]
         self.pyfunc_entries.append(entry)
         return entry
     
@@ -1091,13 +1091,13 @@ class CClassScope(ClassScope):
             # signature declared in advance.
             entry.signature = special_sig
             if special_sig == TypeSlots.unaryfunc:
-                entry.meth_flags = "METH_NOARGS|METH_COEXIST"
+                entry.meth_flags = [TypeSlots.method_noargs, TypeSlots.method_coexist]
             elif special_sig == TypeSlots.binaryfunc or special_sig == TypeSlots.ibinaryfunc:
-                entry.meth_flags = "METH_O|METH_COEXIST"
+                entry.meth_flags = [TypeSlots.method_onearg, TypeSlots.method_coexist]
             else:
                 entry.meth_flags = None # should it generate a wrapper function?
         else:
-            entry.meth_flags = "METH_VARARGS|METH_KEYWORDS"
+            entry.meth_flags = [TypeSlots.method_varargs, TypeSlots.method_keywords]
             entry.signature = pymethod_signature
 
         self.pyfunc_entries.append(entry)
index 530daa2c894f58ead0349a6be5efb775c1ea3c19..fffd8d9e5909a1af73d9d1477ccab8ea11dbbedb 100644 (file)
@@ -590,3 +590,12 @@ MethodSlot(delattrofunc, "", "__delattr__")
 MethodSlot(descrgetfunc, "", "__get__")
 MethodSlot(descrsetfunc, "", "__set__")
 MethodSlot(descrdelfunc, "", "__delete__")
+
+
+# Method flags for python-exposed methods. 
+
+method_noargs   = "METH_NOARGS"
+method_onearg   = "METH_O"
+method_varargs  = "METH_VARARGS"
+method_keywords = "METH_KEYWORDS"
+method_coexist  = "METH_COEXIST"