From 41f215e56afebf58820d3bd0559bd937ce095a02 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Sun, 19 Aug 2007 00:44:50 -0700 Subject: [PATCH] meth_o and meth_noargs for module-level functions previous patch was just for classes --- Cython/Compiler/Code.py | 9 ++++++--- Cython/Compiler/Nodes.py | 10 +++++++--- Cython/Compiler/Symtab.py | 9 --------- Cython/Compiler/TypeSlots.py | 21 +++++++++++++++++++++ 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py index 14fbe2a4..c24541ec 100644 --- a/Cython/Compiler/Code.py +++ b/Cython/Compiler/Code.py @@ -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)) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 4bf256b9..498c9aa9 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -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): diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 88e7af5b..0cdd70d5 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -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 " diff --git a/Cython/Compiler/TypeSlots.py b/Cython/Compiler/TypeSlots.py index fffd8d9e..1f1d414d 100644 --- a/Cython/Compiler/TypeSlots.py +++ b/Cython/Compiler/TypeSlots.py @@ -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 -- 2.26.2