Files
Python3-Win9x/scripts/vc6-typeobject-from-module-and-spec-s-c89.test.py

46 lines
1.8 KiB
Python

#!/usr/bin/env python3
"""Keep the type-spec name pointer C89-safe and initialize it after flags."""
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"\bconst char \*s;", opening), (
"s must be declared in the opening declaration block (C89), before statements"
)
assert len(re.findall(r"\bconst char\s*\*s\b", body)) == 1, "declare s exactly once"
name_setup = body[body.index(" type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE;"):]
name_setup = name_setup[:name_setup.index(" res->ht_name = PyUnicode_FromString(s);")]
assert len(re.findall(r"strrchr\(spec->name, '\.'\)", name_setup)) == 1, (
"evaluate name search exactly once in name setup"
)
expected = """
if (spec->name == NULL) {
PyErr_SetString(PyExc_SystemError,
"Type spec does not define the name field.");
goto fail;
}
type = &res->ht_type;
type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE;
s = strrchr(spec->name, '.');
if (s == NULL) {
s = spec->name;
}
else {
s++;
}
res->ht_name = PyUnicode_FromString(s);
"""
actual = body[body.index(" if (spec->name == NULL)"):
body.index(" if (!res->ht_name)")]
assert actual.split() == expected.split(), (
"preserve name validation, flags, search initialization timing, and name selection"
)
print("PyType_FromModuleAndSpec s C89 declaration and same-point initialization: PASS")