meth_o and meth_noargs for module-level functions
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 19 Aug 2007 07:44:50 +0000 (00:44 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 19 Aug 2007 07:44:50 +0000 (00:44 -0700)
previous patch was just for classes

Cython/Compiler/Code.py
Cython/Compiler/Nodes.py
Cython/Compiler/Symtab.py
Cython/Compiler/TypeSlots.py

index 14fbe2a4f7a6be6e0a0c831341ce971bb37c550d..c24541ecd6863326d78b3de4005a320e7949cb08 100644 (file)
@@ -6,7 +6,7 @@ import Naming
 import Options
 from Cython.Utils import open_new_file
 from PyrexTypes import py_object_type, typecast
-from TypeSlots import get_special_method_signature
+from TypeSlots import get_special_method_signature, method_coexist
 
 class CCodeWriter:
     # f                file            output file
@@ -289,12 +289,15 @@ class CCodeWriter:
             doc_code = entry.doc_cname
         else:
             doc_code = 0
-        if entry.meth_flags:
+        method_flags = entry.signature.method_flags()
+        if method_flags:
+            if get_special_method_signature(entry.name):
+                method_flags += [method_coexist]
             self.putln(
                 '{"%s", (PyCFunction)%s, %s, %s}%s' % (
                     entry.name, 
                     entry.func_cname,
-                    "|".join(entry.meth_flags),
+                    "|".join(method_flags),
                     doc_code,
                     term))
     
index 4bf256b9ee226d1310107fed8bb328aae02926f4..498c9aa99b38f89e449cbbaaedeeef46fb220ecb 100644 (file)
@@ -820,13 +820,17 @@ class DefNode(FuncDefNode):
     
     def analyse_signature(self, env):
         any_type_tests_needed = 0
-        if self.entry.signature is TypeSlots.pymethod_signature:
+        # Use the simpler calling signature for zero- and one-argument functions.
+        if self.entry.signature is TypeSlots.pyfunction_signature:
+            if len(self.args) == 0:
+                self.entry.signature = TypeSlots.pyfunction_noargs
+            elif len(self.args) == 1 and self.args[0].type.is_pyobject and self.args[0].default is None:
+                self.entry.signature = TypeSlots.pyfunction_onearg
+        elif 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):
index 88e7af5b18a775c3eaebc961125434a11d4dccfa..0cdd70d5ea7fe25c112856d044386da69e621a03 100644 (file)
@@ -303,7 +303,6 @@ 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 = [TypeSlots.method_varargs, TypeSlots.method_keywords]
         self.pyfunc_entries.append(entry)
         return entry
     
@@ -1090,14 +1089,7 @@ 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 = [TypeSlots.method_noargs, TypeSlots.method_coexist]
-            elif special_sig == TypeSlots.binaryfunc or special_sig == TypeSlots.ibinaryfunc:
-                entry.meth_flags = [TypeSlots.method_onearg, TypeSlots.method_coexist]
-            else:
-                entry.meth_flags = None # should it generate a wrapper function?
         else:
-            entry.meth_flags = [TypeSlots.method_varargs, TypeSlots.method_keywords]
             entry.signature = pymethod_signature
 
         self.pyfunc_entries.append(entry)
@@ -1181,7 +1173,6 @@ 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 "
index fffd8d9e5909a1af73d9d1477ccab8ea11dbbedb..1f1d414dbfaf32ff54225f7f1e39752618b4ae09 100644 (file)
@@ -82,6 +82,18 @@ class Signature:
     
     def return_type(self):
         return self.format_map[self.ret_format]
+        
+    def method_flags(self):
+        if self.ret_format == "O":
+            full_args = "O" + self.fixed_arg_format if self.has_dummy_arg else self.fixed_arg_format
+            if full_args in ["O", "T"]:
+                if self.has_generic_args:
+                    return [method_varargs, method_keywords]
+                else:
+                    return [method_noargs]
+            elif full_args in ["OO", "TO"] and not self.has_generic_args:
+                return [method_onearg]
+        return None
 
 
 class SlotDescriptor:
@@ -342,6 +354,15 @@ def get_property_accessor_signature(name):
 pyfunction_signature = Signature("-*", "O")
 pymethod_signature = Signature("T*", "O")
 
+#------------------------------------------------------------------------------------------
+#
+#  Signatures for simple Python functions.
+#
+#------------------------------------------------------------------------------------------
+
+pyfunction_noargs = Signature("-", "O")
+pyfunction_onearg = Signature("-O", "O")
+
 #------------------------------------------------------------------------------------------
 #
 #  Signatures for the various kinds of function that