Files
Python3-Win9x/scripts/vc6-typeobject-mro-implementation-result-c89.test.py
T

52 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Check the slow-path MRO result declaration and allocation order for C89."""
import re
from pathlib import Path
source = Path("cpython/Objects/typeobject.c").read_text()
match = re.search(
r"\nstatic PyObject \*\nmro_implementation\(PyTypeObject \*type\)\n\{(.*?)\n\}",
source,
re.S,
)
assert match, "mro_implementation definition missing"
body = match.group(1)
opening = body.split("if (!_PyType_IsReady(type))", 1)[0]
assert re.search(r"\bPyObject \*result;", opening), (
"mro_implementation: PyObject *result; must precede statements (C89)"
)
assert len(re.findall(r"\bPyObject \*result;", body)) == 1, (
"declare the slow-path result exactly once without initialization"
)
expected = """
for (i = 0; i < n; i++) {
PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, i));
to_merge[i] = base->tp_mro;
}
to_merge[n] = bases;
result = PyList_New(1);
if (result == NULL) {
PyMem_Free(to_merge);
return NULL;
}
Py_INCREF(type);
PyList_SET_ITEM(result, 0, (PyObject *)type);
if (pmerge(result, to_merge, n + 1) < 0) {
Py_CLEAR(result);
}
PyMem_Free(to_merge);
return result;
"""
tail = body[body.index(" for (i = 0; i < n; i++)", body.index("to_merge = PyMem_New")):]
assert tail.split() == expected.split(), (
"preserve result allocation after merge-array population and all subsequent control flow"
)
assert body.count("PyList_New(1)") == 1, "allocate the slow-path result exactly once"
assert "PyObject *result = PyTuple_New(k + 1);" in body, (
"preserve the separate fast-path result initialization"
)
print("mro_implementation result C89 declaration and unchanged allocation order: PASS")