Files
Python3-Win9x/scripts/vc6-typeobject-from-module-and-spec-name-buf-len-c89.test.py
T

43 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Keep the type-spec name buffer length C89-safe at its evaluation point."""
import re
from pathlib import Path
source = Path("cpython/Objects/typeobject.c").read_text()
match = re.search(
r"\nPyObject \*\nPyType_FromModuleAndSpec\(PyObject \*module, PyType_Spec \*spec, PyObject \*bases\)\n"
r"\{(.*?)\n\}", source, re.S,
)
assert match, "PyType_FromModuleAndSpec definition missing"
body = re.sub(r"/\*.*?\*/|//[^\n]*", "", match.group(1), flags=re.S)
opening = body[:body.index(" nmembers = weaklistoffset")]
assert re.search(r"\bPy_ssize_t name_buf_len;", opening), (
"name_buf_len must be declared in the opening declaration block (C89), before statements"
)
assert len(re.findall(r"\bPy_ssize_t\s+name_buf_len\b", body)) == 1, (
"declare name_buf_len exactly once"
)
assert len(re.findall(r"\bname_buf_len\s*=", body)) == 1, (
"assign name_buf_len exactly once"
)
expected = """
res->ht_name = PyUnicode_FromString(s);
if (!res->ht_name) {
goto fail;
}
res->ht_qualname = Py_NewRef(res->ht_name);
name_buf_len = strlen(spec->name) + 1;
res->_ht_tpname = PyMem_Malloc(name_buf_len);
if (res->_ht_tpname == NULL) {
goto fail;
}
type->tp_name = memcpy(res->_ht_tpname, spec->name, name_buf_len);
res->ht_module = Py_XNewRef(module);
"""
actual = body[body.index(" res->ht_name = PyUnicode_FromString(s);"):
body.index(" if (!bases)")]
assert actual.split() == expected.split(), (
"preserve name creation, length evaluation timing, allocation, failure handling, and copy"
)
print("PyType_FromModuleAndSpec name_buf_len C89 declaration and same-point initialization: PASS")