Files
Python3-Win9x/scripts/vc6-typeobject-subtype-dealloc-type-needs-decref-c89.test.py
T

55 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""Keep only non-GC subtype_dealloc's type_needs_decref C89-safe."""
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 void\nsubtype_dealloc\(PyObject \*self\)\n\{(.*?)\n\}",
source,
re.S,
)
assert match, "subtype_dealloc definition missing"
body = match.group(1)
start = body.index(" if (!_PyType_IS_GC(type)) {")
end = body.index(" /* We get here only if the type has GC */", start)
branch = re.sub(r"/\*.*?\*/|//[^\n]*", "", body[start:end], flags=re.S)
assert re.match(r"\s*if \(!_PyType_IS_GC\(type\)\) \{\s*int type_needs_decref;", branch), (
"non-GC subtype_dealloc: type_needs_decref must be declared at block entry (C89)"
)
expected = """
if (!_PyType_IS_GC(type)) {
int type_needs_decref;
if (type->tp_finalize) {
if (PyObject_CallFinalizerFromDealloc(self) < 0)
return;
}
if (type->tp_del) {
type->tp_del(self);
if (Py_REFCNT(self) > 0) {
return;
}
}
base = type;
while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
base = base->tp_base;
assert(base);
}
type = Py_TYPE(self);
type_needs_decref = (type->tp_flags & Py_TPFLAGS_HEAPTYPE
&& !(base->tp_flags & Py_TPFLAGS_HEAPTYPE));
assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0);
assert(basedealloc);
basedealloc(self);
if (type_needs_decref) {
Py_DECREF(type);
}
return;
}
"""
assert branch.split() == expected.split(), (
"non-GC subtype_dealloc: preserve assignment evaluation point and all control flow"
)
print("non-GC subtype_dealloc type_needs_decref C89 declaration and unchanged control flow: PASS")