37 lines
1.3 KiB
Python
37 lines
1.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Check object_new's C89 obj declaration and allocation timing."""
|
|
import re
|
|
from pathlib import Path
|
|
|
|
source = Path("cpython/Objects/typeobject.c").read_text()
|
|
match = re.search(
|
|
r"\nstatic PyObject \*\nobject_new\(PyTypeObject \*type, PyObject \*args, "
|
|
r"PyObject \*kwds\)\n\{(.*?)\n\}", source, re.S,
|
|
)
|
|
assert match, "object_new definition missing"
|
|
body = re.sub(r"/\*.*?\*/|//[^\n]*", "", match.group(1), flags=re.S)
|
|
assert re.match(r"\s*PyObject \*obj;\s*if \(excess_args\(args, kwds\)\)", body), (
|
|
"object_new: obj must be in the opening declaration block (C89)"
|
|
)
|
|
assert len(re.findall(r"\bPyObject\s*\*\s*obj\b", body)) == 1, "declare obj exactly once"
|
|
assert len(re.findall(r"\bobj\s*=(?!=)", body)) == 1, "assign obj exactly once"
|
|
expected = """
|
|
Py_DECREF(joined);
|
|
return NULL;
|
|
}
|
|
obj = type->tp_alloc(type, 0);
|
|
if (obj == NULL) {
|
|
return NULL;
|
|
}
|
|
if (_PyObject_InitializeDict(obj)) {
|
|
Py_DECREF(obj);
|
|
return NULL;
|
|
}
|
|
return obj;
|
|
"""
|
|
assert body[body.index("Py_DECREF(joined);"):].split() == expected.split(), (
|
|
"object_new: preserve allocation after abstract-type rejection, NULL check, "
|
|
"dictionary initialization, cleanup, and return order"
|
|
)
|
|
print("object_new obj C89 declaration and allocation timing: PASS")
|