#!/usr/bin/env python3 """Check only tuplerepeat's dest declaration and allocation-time assignment.""" 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"tuplerepeat\(PyTupleObject \*a, Py_ssize_t n\)\n\{(.*?)\n\}", source.read_text(), re.S, ) assert match, "tuplerepeat definition missing" body = match.group(1) assert re.match( r"\s*Py_ssize_t size;\s*PyTupleObject \*np;\s*PyObject \*\*dest;" r"\s*PyObject \*\*dest_end;\s*if", body, ), "tuplerepeat: dest must be declared in the opening declaration block" assert len(re.findall(r"PyObject\s*\*\*dest\b", body)) == 1, ( "tuplerepeat: exactly one uninitialized dest declaration required" ) assert re.search( r"np = tuple_alloc\(size\);\s*if \(np == NULL\)\s*return NULL;" r"\s*dest = np->ob_item;\s*dest_end = dest \+ size;", body, ), "tuplerepeat: assign dest immediately after allocation/NULL check, before unchanged dest_end" assert len(re.findall(r"\bdest\s*=", body)) == 1, ( "tuplerepeat: exactly one dest assignment required" ) print("tuplerepeat dest C89 declaration and allocation/assignment order: PASS")