#!/usr/bin/env python3 """Regress type_new_slots_impl C89 declaration and assignment timing.""" import re from pathlib import Path source = Path("cpython/Objects/typeobject.c").read_text() match = re.search( r"\nstatic int\ntype_new_slots_impl\(type_new_ctx \*ctx, PyObject \*dict\)\n\{(.*?)\n\}", source, re.S, ) assert match, "type_new_slots_impl definition missing" body = re.sub(r"/\*.*?\*/|//[^\n]*", "", match.group(1), flags=re.S) assert re.match( r"\s*PyObject \*new_slots;\s*if \(ctx->nslot > 0 && ctx->base->tp_itemsize != 0\)", body, ), "type_new_slots_impl: new_slots must be in the opening declaration block (C89)" assert re.search( r'PyErr_Format\(PyExc_TypeError,\s*' r'"nonempty __slots__ not supported for subtype of \'%s\'",\s*' r"ctx->base->tp_name\);\s*return -1;\s*\}" r"\s*if \(type_new_visit_slots\(ctx\) < 0\) \{\s*return -1;\s*\}" r"\s*new_slots = type_new_copy_slots\(ctx, dict\);" r"\s*if \(new_slots == NULL\) \{\s*return -1;\s*\}" r"\s*assert\(PyTuple_CheckExact\(new_slots\)\);" r"\s*Py_XSETREF\(ctx->slots, new_slots\);" r"\s*ctx->nslot = PyTuple_GET_SIZE\(new_slots\);" r"\s*type_new_slots_bases\(ctx\);\s*return 0;\s*$", body, ), "preserve validation, copying, error checks, ownership transfer and secondary-base order" assert len(re.findall(r"PyObject \*new_slots\b", body)) == 1, "declare new_slots exactly once" print("type_new_slots_impl C89 declaration and assignment timing: PASS")