#!/usr/bin/env python3 """Check structseq_dealloc's C89 declarations and teardown order.""" import re import sys from pathlib import Path source = Path(sys.argv[1] if len(sys.argv) > 1 else "cpython/Objects/structseq.c") match = re.search( r"static void\nstructseq_dealloc\(PyStructSequence \*obj\)\n\{(.*?)\n\}", source.read_text(), re.S, ) assert match, "structseq_dealloc definition not found" body = match.group(1) assert re.match(r"\s*Py_ssize_t i, size;\s*PyTypeObject \*tp;", body), ( "structseq_dealloc: tp must be declared without initializer alongside i and " "size before GC untracking; declaration after statement is not C89 compatible" ) expected = """ Py_ssize_t i, size; PyTypeObject *tp; PyObject_GC_UnTrack(obj); tp = Py_TYPE(obj); size = REAL_SIZE(obj); for (i = 0; i < size; ++i) { Py_XDECREF(obj->ob_item[i]); } PyObject_GC_Del(obj); if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) { Py_DECREF(tp); } """ assert re.sub(r"\s+", "", body) == re.sub(r"\s+", "", expected), ( "preserve GC untracking before type capture and size lookup, item decref " "order, GC deletion, and conditional heap-type decref" ) print("structseq_dealloc C89 declarations and teardown order: PASS")