#!/usr/bin/env python3 """Check NewType's C89 slot assignments and preserve all eight slot pairs.""" 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"\n_PyStructSequence_NewType\([^\n]*\)\n\{.*?" r"/\* Initialize Slots \*/(.*?)/\* Initialize Spec \*/", source.read_text(), re.S, ) assert match, "_PyStructSequence_NewType slots initialization not found" body = match.group(1) assert not re.search(r"\(\s*PyType_Slot\s*\)\s*\{", body), ( "_PyStructSequence_NewType: compound-literal slot initializers are not C89 compatible" ) pairs = [ ("Py_tp_dealloc", "(destructor)structseq_dealloc"), ("Py_tp_repr", "(reprfunc)structseq_repr"), ("Py_tp_doc", "(void *)desc->doc"), ("Py_tp_methods", "structseq_methods"), ("Py_tp_new", "structseq_new"), ("Py_tp_members", "members"), ("Py_tp_traverse", "(traverseproc)structseq_traverse"), ("0", "0"), ] expected = "\n".join( f"slots[{i}].slot = {slot}; slots[{i}].pfunc = {value};" for i, (slot, value) in enumerate(pairs) ) assert re.sub(r"\s+", "", body) == re.sub(r"\s+", "", expected), ( "preserve all slot values, ordering, casts, and the zero sentinel" ) print("_PyStructSequence_NewType C89 slots, values, ordering, casts, and sentinel: PASS")