Files
Python3-Win9x/scripts/vc6-typeobject-lookup-maybe-method-c89.test.py

50 lines
1.6 KiB
Python

#!/usr/bin/env python3
"""Keep lookup_maybe_method's descriptor getter C89-safe without reordering."""
import re
import sys
from pathlib import Path
source = Path(sys.argv[1] if len(sys.argv) > 1 else "cpython/Objects/typeobject.c").read_text()
match = re.search(
r"\nstatic PyObject \*\nlookup_maybe_method\(PyObject \*self, PyObject \*attr, int \*unbound\)\n\{(.*?)\n\}",
source,
re.S,
)
assert match, "lookup_maybe_method definition missing"
body = match.group(1)
assert re.match(
r"\s*PyObject \*res = _PyType_Lookup\(Py_TYPE\(self\), attr\);\s*descrgetfunc f;",
body,
), "lookup_maybe_method: f must be declared in the opening declaration block (C89)"
assert len(re.findall(r"\bdescrgetfunc\s+f\b", body)) == 1, (
"lookup_maybe_method: declare the descriptor getter exactly once"
)
expected = """
PyObject *res = _PyType_Lookup(Py_TYPE(self), attr);
descrgetfunc f;
if (res == NULL) {
return NULL;
}
if (_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)) {
/* Avoid temporary PyMethodObject */
*unbound = 1;
Py_INCREF(res);
}
else {
*unbound = 0;
f = Py_TYPE(res)->tp_descr_get;
if (f == NULL) {
Py_INCREF(res);
}
else {
res = f(res, self, (PyObject *)(Py_TYPE(self)));
}
}
return res;
"""
assert body.split() == expected.split(), (
"lookup_maybe_method: preserve getter evaluation after *unbound = 0 and all control flow"
)
print("lookup_maybe_method descriptor getter C89 declaration and unchanged evaluation/control flow: PASS")