37 lines
1.3 KiB
Python
37 lines
1.3 KiB
Python
#!/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")
|