Files
Python3-Win9x/scripts/vc6-typeobject-set-annotations-c89.test.py
T

50 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Check type_set_annotations's C89 local and unchanged executable body."""
import re
from pathlib import Path
source = Path("cpython/Objects/typeobject.c").read_text()
match = re.search(
r"\nstatic int\ntype_set_annotations\(PyTypeObject \*type, PyObject \*value, void \*context\)\n\{(.*?)\n\}",
source,
re.S,
)
assert match, "type_set_annotations definition missing"
body = match.group(1)
assert re.match(r"\s*int result;\s*if\b", body), (
"type_set_annotations: result must be declared before the immutable-type guard"
)
assert len(re.findall(r"\bint\s+result\b", body)) == 1, (
"type_set_annotations: declare result exactly once"
)
expected = """
int result;
if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) {
PyErr_Format(PyExc_TypeError,
"cannot set '__annotations__' attribute of immutable type '%s'",
type->tp_name);
return -1;
}
if (value != NULL) {
/* set */
result = PyDict_SetItem(type->tp_dict, &_Py_ID(__annotations__), value);
} else {
/* delete */
result = PyDict_DelItem(type->tp_dict, &_Py_ID(__annotations__));
if (result < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
PyErr_SetString(PyExc_AttributeError, "__annotations__");
}
}
if (result == 0) {
PyType_Modified(type);
}
return result;
"""
assert body.split() == expected.split(), (
"type_set_annotations: preserve guard, assignments, set/delete branches, "
"error handling, invalidation, and return in their original order"
)
print("type_set_annotations result C89 declaration and unchanged executable body: PASS")