Files
Python3-Win9x/scripts/vc6-typeobject-get-subclasses-index-c89.test.py

61 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Keep _PyType_GetSubclasses's index in opening C89 locals."""
import re
from pathlib import Path
source = Path("cpython/Objects/typeobject.c").read_text()
match = re.search(
r"\nPyObject\*\n_PyType_GetSubclasses\(PyTypeObject \*self\)\n\{(.*?)\n\}",
source,
re.S,
)
assert match, "_PyType_GetSubclasses definition missing"
body = re.sub(r"/\*.*?\*/|//[^\n]*", "", match.group(1), flags=re.S)
assert re.match(
r"\s*PyObject \*subclasses;\s*Py_ssize_t i;\s*"
r"PyObject \*list = PyList_New\(0\);",
body,
), "_PyType_GetSubclasses: i must be declared in the opening declaration block (C89)"
assert len(re.findall(r"\bPy_ssize_t\s+i\b", body)) == 1, (
"_PyType_GetSubclasses: declare i exactly once"
)
expected = """
PyObject *subclasses;
Py_ssize_t i;
PyObject *list = PyList_New(0);
PyObject *ref;
PyObject *obj;
if (list == NULL) {
return NULL;
}
subclasses = self->tp_subclasses;
if (subclasses == NULL) {
return list;
}
assert(PyDict_CheckExact(subclasses));
i = 0;
while (PyDict_Next(subclasses, &i, NULL, &ref)) {
assert(PyWeakref_CheckRef(ref));
obj = PyWeakref_GET_OBJECT(ref);
if (obj == Py_None) {
continue;
}
assert(PyType_Check(obj));
if (PyList_Append(list, obj) < 0) {
Py_DECREF(list);
return NULL;
}
}
return list;
"""
assert body.split() == expected.split(), (
"_PyType_GetSubclasses: preserve index initialization timing, guards, loop, "
"and ref/obj uses"
)
print("_PyType_GetSubclasses C89 index declaration and preserved initialization timing: PASS")