Commit 8c68f604 authored by Robert Bradshaw's avatar Robert Bradshaw

Avoid call to PyArg_ParseTupleAndKeywords for zero- and single-argument functions.

parent 57edf105
......@@ -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))
......
......@@ -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"
......
......@@ -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)
......
......@@ -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"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment