Files
Python3-Win9x/scripts/vc6-typeobject-set-bases-res-c89.test.py

34 lines
1.6 KiB
Python

"""Check type_set_bases declares res with opening locals without moving assignments."""
from pathlib import Path
import re
import sys
source = Path(sys.argv[1] if len(sys.argv) > 1 else "cpython/Objects/typeobject.c").read_text()
match = re.search(
r"\nstatic int\ntype_set_bases\(PyTypeObject \*type, PyObject \*new_bases, void \*context\)\n\{(.*?)\n\}",
source,
re.S,
)
assert match, "type_set_bases definition missing"
body = match.group(1)
assert re.search(
r"\A\n\s*Py_ssize_t n;\n\s*Py_ssize_t i;\n\s*PyTypeObject \*new_base;\n"
r"\s*PyObject \*old_bases;\n\s*PyTypeObject \*old_base;\n\s*PyObject \*temp;\n\s*int res;",
body,
), "type_set_bases: res must be declared with the opening locals"
assert body.count("int res;") == 1, "res declaration must occur once"
assert re.findall(r"\bres\s*=\s*([^;]+);", body) == [
"0", "add_all_subclasses(type, new_bases)", "0",
], "type_set_bases: preserve all res assignments and their order"
without_comments = re.sub(r"/\*.*?\*/|//[^\n]*", "", body, flags=re.S)
assert re.search(
r"if \(mro_hierarchy\(type, temp\) < 0\) \{\s*goto undo;\s*\}\s*"
r"Py_DECREF\(temp\);\s*res = 0;\s*if \(type->tp_bases == new_bases\) \{\s*"
r"remove_all_subclasses\(type, old_bases\);\s*"
r"res = add_all_subclasses\(type, new_bases\);\s*update_all_slots\(type\);\s*"
r"\}\s*else \{\s*res = 0;\s*\}\s*"
r"Py_DECREF\(old_bases\);\s*Py_DECREF\(old_base\);\s*"
r"assert\(_PyType_CheckConsistency\(type\)\);\s*return res;",
without_comments,
), "type_set_bases: preserve res assignment evaluation and control-flow order"