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

55 lines
2.0 KiB
Python

#!/usr/bin/env python3
"""Check type_get_annotations's C89 local and preserve every executable statement."""
import re
from pathlib import Path
source = Path("cpython/Objects/typeobject.c").read_text()
match = re.search(
r"\nstatic PyObject \*\ntype_get_annotations\(PyTypeObject \*type, void \*context\)\n\{(.*?)\n\}",
source,
re.S,
)
assert match, "type_get_annotations definition missing"
body = match.group(1)
assert re.match(r"\s*PyObject \*annotations;\s*if\b", body), (
"type_get_annotations: annotations must be declared before the heap-type guard"
)
assert len(re.findall(r"\bPyObject\s*\*\s*annotations\b", body)) == 1, (
"type_get_annotations: declare annotations exactly once"
)
expected = """
PyObject *annotations;
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
PyErr_Format(PyExc_AttributeError, "type object '%s' has no attribute '__annotations__'", type->tp_name);
return NULL;
}
annotations = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__annotations__));
if (annotations) {
if (Py_TYPE(annotations)->tp_descr_get) {
annotations = Py_TYPE(annotations)->tp_descr_get(
annotations, NULL, (PyObject *)type);
} else {
Py_INCREF(annotations);
}
}
else if (!PyErr_Occurred()) {
annotations = PyDict_New();
if (annotations) {
int result = PyDict_SetItem(
type->tp_dict, &_Py_ID(__annotations__), annotations);
if (result) {
Py_CLEAR(annotations);
} else {
PyType_Modified(type);
}
}
}
return annotations;
"""
assert body.split() == expected.split(), (
"type_get_annotations: preserve guard, lookup, descriptor handling, references, "
"dictionary creation, error handling, invalidation, and return in their original order"
)
print("type_get_annotations annotations C89 declaration and unchanged executable body: PASS")