#!/usr/bin/env python3 """Check only _PyTuple_FromArraySteal's dst declaration and evaluation point.""" 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"PyObject \*\n_PyTuple_FromArraySteal\(PyObject \*const \*src, Py_ssize_t n\)\n\{(.*?)\n\}", source.read_text(), re.S, ) assert match, "_PyTuple_FromArraySteal definition not found" body = match.group(1) assert re.match( r"\s*PyTupleObject \*tuple;\s*Py_ssize_t i;\s*PyObject \*\*dst;\s*if \(n == 0\)", body, ), "_PyTuple_FromArraySteal: function-scope PyObject **dst must precede statements" expected = """ PyTupleObject *tuple; Py_ssize_t i; PyObject **dst; if (n == 0) { return tuple_get_empty(); } tuple = tuple_alloc(n); if (tuple == NULL) { for (i = 0; i < n; i++) { Py_DECREF(src[i]); } return NULL; } dst = tuple->ob_item; for (i = 0; i < n; i++) { PyObject *item = src[i]; dst[i] = item; } _PyObject_GC_TRACK(tuple); return (PyObject *)tuple; """ assert re.sub(r"\s+", "", body) == re.sub(r"\s+", "", expected), ( "preserve dst assignment immediately after successful allocation and NULL " "check, failure DECREFs/return, loop index and item declarations, stores, " "GC tracking and return order" ) print("_PyTuple_FromArraySteal dst declaration placement and evaluation/refcount/error order: PASS")