#!/usr/bin/env python3 """Check tuple_vectorcall's C89 nargs declaration and evaluation order.""" import re import sys from pathlib import Path source = Path(sys.argv[1] if len(sys.argv) > 1 else "cpython/Objects/tupleobject.c") match = re.search( r"static PyObject \*\ntuple_vectorcall\([^)]*\)\n\{(.*?)\n\}", source.read_text(), re.S, ) assert match, "tuple_vectorcall definition not found" body = match.group(1) assert re.match(r"\s*Py_ssize_t nargs;", body), ( "tuple_vectorcall: nargs must be declared in the initial declaration block " "before the keyword check for C89 compatibility" ) expected = """ Py_ssize_t nargs; if (!_PyArg_NoKwnames("tuple", kwnames)) { return NULL; } nargs = PyVectorcall_NARGS(nargsf); if (!_PyArg_CheckPositional("tuple", nargs, 0, 1)) { return NULL; } if (nargs) { return tuple_new_impl(_PyType_CAST(type), args[0]); } else { return tuple_get_empty(); } """ assert re.sub(r"\s+", "", body) == re.sub(r"\s+", "", expected), ( "preserve keyword rejection before the single nargs evaluation, positional " "validation, and nonempty/empty tuple return paths" ) print("tuple_vectorcall C89 nargs declaration and evaluation order: PASS")