Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0c8c389

Browse files
committed
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.
1 parent 998c209 commit 0c8c389

1 file changed

Lines changed: 32 additions & 14 deletions

File tree

Tools/clinic/clinic.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -705,14 +705,14 @@ def output_templates(self, f):
705705
{c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs)
706706
""")
707707

708-
parser_prototype_fastcall = normalize_snippet("""
708+
parser_prototype_varargs = normalize_snippet("""
709709
static PyObject *
710-
{c_basename}({self_type}{self_name}, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
710+
{c_basename}({self_type}{self_name}, PyObject *args)
711711
""")
712712

713-
parser_prototype_varargs = normalize_snippet("""
713+
parser_prototype_fastcall = normalize_snippet("""
714714
static PyObject *
715-
{c_basename}({self_type}{self_name}, PyObject *args)
715+
{c_basename}({self_type}{self_name}, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
716716
""")
717717

718718
# parser_body_fields remembers the fields passed in to the
@@ -837,18 +837,36 @@ def insert_keywords(s):
837837
""", indent=4))
838838

839839
elif positional:
840-
# positional-only, but no option groups
841-
# we only need one call to PyArg_ParseTuple
840+
if not new_or_init:
841+
# positional-only, but no option groups
842+
# we only need one call to _PyArg_ParseStack
842843

843-
flags = "METH_VARARGS"
844-
parser_prototype = parser_prototype_varargs
844+
flags = "METH_FASTCALL"
845+
parser_prototype = parser_prototype_fastcall
845846

846-
parser_definition = parser_body(parser_prototype, normalize_snippet("""
847-
if (!PyArg_ParseTuple(args, "{format_units}:{name}",
848-
{parse_arguments})) {{
849-
goto exit;
850-
}}
851-
""", indent=4))
847+
parser_definition = parser_body(parser_prototype, normalize_snippet("""
848+
if (!_PyArg_ParseStack(args, nargs, "{format_units}:{name}",
849+
{parse_arguments})) {{
850+
goto exit;
851+
}}
852+
853+
if ({self_type_check}!_PyArg_NoStackKeywords("{name}", kwnames)) {{
854+
goto exit;
855+
}}
856+
""", indent=4))
857+
else:
858+
# positional-only, but no option groups
859+
# we only need one call to PyArg_ParseTuple
860+
861+
flags = "METH_VARARGS"
862+
parser_prototype = parser_prototype_varargs
863+
864+
parser_definition = parser_body(parser_prototype, normalize_snippet("""
865+
if (!PyArg_ParseTuple(args, "{format_units}:{name}",
866+
{parse_arguments})) {{
867+
goto exit;
868+
}}
869+
""", indent=4))
852870

853871
elif not new_or_init:
854872
flags = "METH_FASTCALL"

0 commit comments

Comments
 (0)