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

37 lines
1.5 KiB
Python

#!/usr/bin/env python3
"""Keep _PyType_GetSubclasses's obj 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\);\s*PyObject \*ref;\s*"
r"PyObject \*obj;",
body,
), "_PyType_GetSubclasses: obj must be in the opening declaration block (C89)"
assert len(re.findall(r"\bPyObject\s*\*\s*obj\b", body)) == 1, (
"_PyType_GetSubclasses: declare obj exactly once without initialization"
)
assert body.count("PyWeakref_GET_OBJECT(ref)") == 1, (
"_PyType_GetSubclasses: preserve the single weakref object read"
)
assert re.search(
r"while \(PyDict_Next\(subclasses, &i, NULL, &ref\)\) \{\s*"
r"assert\(PyWeakref_CheckRef\(ref\)\);\s*"
r"obj = PyWeakref_GET_OBJECT\(ref\);\s*"
r"if \(obj == Py_None\) \{\s*continue;\s*\}\s*"
r"assert\(PyType_Check\(obj\)\);\s*"
r"if \(PyList_Append\(list, obj\) < 0\) \{\s*"
r"Py_DECREF\(list\);\s*return NULL;\s*\}\s*\}\s*return list;\s*$",
body,
), "_PyType_GetSubclasses: preserve obj assignment timing and loop control flow"
print("_PyType_GetSubclasses obj C89 declaration and preserved assignment timing: PASS")