From: Lisandro Dalcin Date: Tue, 28 Apr 2009 13:25:43 +0000 (-0300) Subject: compiler directive to control METH_O and METH_NOARGS flags (ticket #295) X-Git-Tag: 0.11.2.rc1~10^2~36^2~9 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=a837633595d5830af5b01d5b369f12cbafaf1159;p=cython.git compiler directive to control METH_O and METH_NOARGS flags (ticket #295) --- diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 1638189d..b6c7f72c 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1691,9 +1691,11 @@ class DefNode(FuncDefNode): def analyse_signature(self, env): any_type_tests_needed = 0 - # Use the simpler calling signature for zero- and one-argument functions. - if not self.entry.is_special and not self.star_arg and not self.starstar_arg: - if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods: + if self.entry.is_special: + self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg) + elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg): + # 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: @@ -1705,8 +1707,6 @@ class DefNode(FuncDefNode): elif len(self.args) == 2: if self.args[1].default is None and not self.args[1].kw_only: self.entry.signature = TypeSlots.ibinaryfunc - elif self.entry.is_special: - self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg) sig = self.entry.signature nfixed = sig.num_fixed_args() for i in range(nfixed): diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py index 286b143c..06f70244 100644 --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py @@ -45,11 +45,6 @@ lookup_module_cpdef = 0 # WARNING: This is a work in progress, may currently segfault. init_local_none = 1 -# Optimize no argument and one argument methods by using the METH_O and METH_NOARGS -# calling conventions. These are faster calling conventions, but disallow the use of -# keywords (which, admittedly, are of little use in these cases). -optimize_simple_methods = 1 - # Append the c file and line number to the traceback for exceptions. c_line_in_traceback = 1 @@ -68,6 +63,7 @@ option_defaults = { 'auto_cpdef': False, 'cdivision': True, # Will be False in 0.12 'cdivision_warnings': False, + 'always_allow_keywords': False, } # Override types possibilities above, if needed diff --git a/tests/run/always_allow_keywords_T295.pyx b/tests/run/always_allow_keywords_T295.pyx new file mode 100644 index 00000000..3ead8145 --- /dev/null +++ b/tests/run/always_allow_keywords_T295.pyx @@ -0,0 +1,60 @@ +__doc__ = """ +>>> func1(None) +>>> func1(*[None]) +>>> func1(arg=None) +Traceback (most recent call last): +... +TypeError: func1() takes no keyword arguments +>>> func2(None) +>>> func2(*[None]) +>>> func2(arg=None) +Traceback (most recent call last): +... +TypeError: func2() takes no keyword arguments +>>> func3(None) +>>> func3(*[None]) +>>> func3(arg=None) + +>>> A().meth1(None) +>>> A().meth1(*[None]) +>>> A().meth1(arg=None) +Traceback (most recent call last): +... +TypeError: meth1() takes no keyword arguments +>>> A().meth2(None) +>>> A().meth2(*[None]) +>>> A().meth2(arg=None) +Traceback (most recent call last): +... +TypeError: meth2() takes no keyword arguments +>>> A().meth3(None) +>>> A().meth3(*[None]) +>>> A().meth3(arg=None) +""" + +cimport cython + + +def func1(arg): + pass + +@cython.always_allow_keywords(False) +def func2(arg): + pass + +@cython.always_allow_keywords(True) +def func3(arg): + pass + +cdef class A: + + def meth1(self, arg): + pass + + @cython.always_allow_keywords(False) + def meth2(self, arg): + pass + + @cython.always_allow_keywords(True) + def meth3(self, arg): + pass