#!/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")