#!/usr/bin/env python3 """Check mro_check's C89 base declaration and validation/cast order.""" import re from pathlib import Path source = Path("cpython/Objects/typeobject.c").read_text() match = re.search( r"\nstatic int\nmro_check\(PyTypeObject \*type, PyObject \*mro\)\n\{(.*?)\n\}", source, re.S, ) assert match, "mro_check definition missing" body = match.group(1) loop = body[body.index(" for (i = 0; i < n; i++) {"):] opening = loop.split("if (!PyType_Check(obj))", 1)[0] assert re.search(r"\bPyTypeObject \*base;", opening), ( "mro_check: PyTypeObject *base; must precede loop statements (C89)" ) expected = """ for (i = 0; i < n; i++) { PyObject *obj = PyTuple_GET_ITEM(mro, i); PyTypeObject *base; if (!PyType_Check(obj)) { PyErr_Format( PyExc_TypeError, "mro() returned a non-class ('%.500s')", Py_TYPE(obj)->tp_name); return -1; } base = (PyTypeObject*)obj; if (!PyType_IsSubtype(solid, solid_base(base))) { PyErr_Format( PyExc_TypeError, "mro() returned base with unsuitable layout ('%.500s')", base->tp_name); return -1; } } return 0; """ assert loop.split() == expected.split(), ( "preserve item lookup, non-class rejection before cast, layout validation, and returns" ) print("mro_check C89 base declaration and unchanged validation/cast order: PASS")