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
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))
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):
# 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
# 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)
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 "
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:
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