43 lines
1.4 KiB
Python
43 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Keep type-spec doc locals C89-safe without moving their evaluations."""
|
|
import re
|
|
from pathlib import Path
|
|
|
|
source = Path("cpython/Objects/typeobject.c").read_text()
|
|
match = re.search(
|
|
r"\nPyObject \*\nPyType_FromModuleAndSpec\(PyObject \*module, PyType_Spec \*spec, PyObject \*bases\)\n"
|
|
r"\{(.*?)\n\}", source, re.S,
|
|
)
|
|
assert match, "PyType_FromModuleAndSpec definition missing"
|
|
body = re.sub(r"/\*.*?\*/|//[^\n]*", "", match.group(1), flags=re.S)
|
|
match = re.search(
|
|
r"else if \(slot->slot == Py_tp_doc\) \{(.*?)\n \}"
|
|
r"\s*else if \(slot->slot == Py_tp_members\)", body, re.S,
|
|
)
|
|
assert match, "Py_tp_doc branch missing"
|
|
branch = match.group(1)
|
|
assert re.match(r"\s*size_t len;\s*char \*tp_doc;\s*if", branch), (
|
|
"len and tp_doc must be declared at the start of the Py_tp_doc block (C89)"
|
|
)
|
|
expected = """
|
|
size_t len;
|
|
char *tp_doc;
|
|
if (slot->pfunc == NULL) {
|
|
type->tp_doc = NULL;
|
|
continue;
|
|
}
|
|
len = strlen(slot->pfunc)+1;
|
|
tp_doc = PyObject_Malloc(len);
|
|
if (tp_doc == NULL) {
|
|
type->tp_doc = NULL;
|
|
PyErr_NoMemory();
|
|
goto fail;
|
|
}
|
|
memcpy(tp_doc, slot->pfunc, len);
|
|
type->tp_doc = tp_doc;
|
|
"""
|
|
assert branch.split() == expected.split(), (
|
|
"preserve NULL guard, length/allocation evaluation order, failure handling, and copy"
|
|
)
|
|
print("PyType_FromModuleAndSpec doc locals C89 declarations and evaluation order: PASS")
|