summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-01-17 00:42:54 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2017-01-17 00:42:54 (GMT)
commit0c8c3893ae29fab8ce9db0c2f5b52acbe89032e1 (patch)
tree86e701e8cde526f18fc8b6323dafd2ea2c2d457b
parent998c20962ca3e2e693c1635efe76c0144dde76fc (diff)
downloadcpython-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-xTools/clinic/clinic.py46
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"