Files
Python3-Win9x/scripts/vc6-typeobject-custom-mro-c89.test.py

49 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Check custom_mro's C89 declaration and lookup/decref evaluation order."""
import re
from pathlib import Path
source = Path("cpython/Objects/typeobject.c").read_text()
start = source.index("type_mro_modified(PyTypeObject *type, PyObject *bases) {")
end = source.index("\n}", start)
function = source[start:end]
start = function.index(" if (custom) {")
end = function.index("\n n = PyTuple_GET_SIZE(bases);", start)
block = function[start:end]
assert re.match(
r"if \(custom\) \{\s*PyObject \*mro_meth, \*type_mro_meth;\s*"
r"int custom_mro;\s*mro_meth =",
block.strip(),
), "custom_mro must be declared in the opening declaration block"
assert len(re.findall(r"\bint\s+custom_mro\b", function)) == 1, (
"declare custom_mro exactly once"
)
expected = """
if (custom) {
PyObject *mro_meth, *type_mro_meth;
int custom_mro;
mro_meth = lookup_maybe_method(
(PyObject *)type, &_Py_ID(mro), &unbound);
if (mro_meth == NULL) {
goto clear;
}
type_mro_meth = lookup_maybe_method(
(PyObject *)&PyType_Type, &_Py_ID(mro), &unbound);
if (type_mro_meth == NULL) {
Py_DECREF(mro_meth);
goto clear;
}
custom_mro = (mro_meth != type_mro_meth);
Py_DECREF(mro_meth);
Py_DECREF(type_mro_meth);
if (custom_mro) {
goto clear;
}
}
"""
assert block.split() == expected.split(), (
"preserve both successful lookups before custom_mro assignment, "
"then decrefs and conditional, including lookup failure handling"
)
print("type_mro_modified custom_mro C89 declaration and evaluation order: PASS")