diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2017-01-17 00:42:54 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2017-01-17 00:42:54 (GMT) |
commit | 0c8c3893ae29fab8ce9db0c2f5b52acbe89032e1 (patch) | |
tree | 86e701e8cde526f18fc8b6323dafd2ea2c2d457b | |
parent | 998c20962ca3e2e693c1635efe76c0144dde76fc (diff) | |
download | cpython-0c8c3893ae29fab8ce9db0c2f5b52acbe89032e1.zip cpython-0c8c3893ae29fab8ce9db0c2f5b52acbe89032e1.tar.gz cpython-0c8c3893ae29fab8ce9db0c2f5b52acbe89032e1.tar.bz2 |
Argument Clinic: Use METH_FASTCALL for positionals
Issue #29286. Use METH_FASTCALL calling convention instead of METH_VARARGS to
parse position arguments. METH_FASTCALL is faster since it avoids the creation
of a temporary tuple to pass positional arguments.
-rwxr-xr-x | Tools/clinic/clinic.py | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 4d84d49..7c4b388 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -705,14 +705,14 @@ class CLanguage(Language): {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) """) - parser_prototype_fastcall = normalize_snippet(""" + parser_prototype_varargs = normalize_snippet(""" static PyObject * - {c_basename}({self_type}{self_name}, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) + {c_basename}({self_type}{self_name}, PyObject *args) """) - parser_prototype_varargs = normalize_snippet(""" + parser_prototype_fastcall = normalize_snippet(""" static PyObject * - {c_basename}({self_type}{self_name}, PyObject *args) + {c_basename}({self_type}{self_name}, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) """) # parser_body_fields remembers the fields passed in to the @@ -837,18 +837,36 @@ class CLanguage(Language): """, indent=4)) elif positional: - # positional-only, but no option groups - # we only need one call to PyArg_ParseTuple + if not new_or_init: + # positional-only, but no option groups + # we only need one call to _PyArg_ParseStack - flags = "METH_VARARGS" - parser_prototype = parser_prototype_varargs + flags = "METH_FASTCALL" + parser_prototype = parser_prototype_fastcall - parser_definition = parser_body(parser_prototype, normalize_snippet(""" - if (!PyArg_ParseTuple(args, "{format_units}:{name}", - {parse_arguments})) {{ - goto exit; - }} - """, indent=4)) + parser_definition = parser_body(parser_prototype, normalize_snippet(""" + if (!_PyArg_ParseStack(args, nargs, "{format_units}:{name}", + {parse_arguments})) {{ + goto exit; + }} + + if ({self_type_check}!_PyArg_NoStackKeywords("{name}", kwnames)) {{ + goto exit; + }} + """, indent=4)) + else: + # positional-only, but no option groups + # we only need one call to PyArg_ParseTuple + + flags = "METH_VARARGS" + parser_prototype = parser_prototype_varargs + + parser_definition = parser_body(parser_prototype, normalize_snippet(""" + if (!PyArg_ParseTuple(args, "{format_units}:{name}", + {parse_arguments})) {{ + goto exit; + }} + """, indent=4)) elif not new_or_init: flags = "METH_FASTCALL" |