41 lines
1.4 KiB
Python
41 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Check only mro_implementation's to_merge declaration and allocation timing."""
|
|
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 = re.sub(r"/\*.*?\*/", "", match.group(1), flags=re.S)
|
|
assert re.match(
|
|
r"\s*PyObject \*bases;\s*Py_ssize_t n;\s*Py_ssize_t i;"
|
|
r"\s*PyObject \*\*to_merge;\s*PyObject \*result;\s*if\b", body
|
|
), "mro_implementation: PyObject **to_merge; must be in the opening declaration block"
|
|
assert len(re.findall(r"\bPyObject\s*\*\*\s*to_merge\b", body)) == 1, (
|
|
"mro_implementation: declare to_merge exactly once"
|
|
)
|
|
assert len(re.findall(r"\bto_merge\s*=(?!=)", body)) == 1, (
|
|
"mro_implementation: assign to_merge exactly once"
|
|
)
|
|
expected = """
|
|
if (check_duplicates(bases) < 0) {
|
|
return NULL;
|
|
}
|
|
to_merge = PyMem_New(PyObject *, n + 1);
|
|
if (to_merge == NULL) {
|
|
PyErr_NoMemory();
|
|
return NULL;
|
|
}
|
|
"""
|
|
allocation = re.split(
|
|
r"\bfor\s*\(", body[body.index("if (check_duplicates(bases)"):], maxsplit=1
|
|
)[0]
|
|
assert allocation.split() == expected.split(), (
|
|
"mro_implementation: preserve allocation after duplicate validation and error handling"
|
|
)
|
|
print("mro_implementation to_merge C89 declaration and unchanged allocation timing: PASS")
|