#!/usr/bin/env python3 """Focused Visual C++ 6.0 C89 regression checks for object.c.""" import re import sys from pathlib import Path source = Path(sys.argv[1]).read_text() def body(name): found = re.search(re.escape(name) + r"\s*\([^;]*\)\s*\{(?P.*?)\n\}", source, re.S) assert found, name + " definition not found" return found.group("body") def check(name, tokens, message): text = body(name) positions = [text.find(token) for token in tokens] assert all(position >= 0 for position in positions) and positions == sorted(positions), message return text text = check("PyObject_CallFinalizerFromDealloc", ( "Py_ssize_t refcnt;", "if (Py_REFCNT(self) != 0)", "refcnt = Py_REFCNT(self);", "_Py_NewReference(self);", "Py_SET_REFCNT(self, refcnt);", ), "PyObject_CallFinalizerFromDealloc must hoist refcnt while preserving resurrection order") assert "Py_ssize_t refcnt =" not in text print("object PyObject_CallFinalizerFromDealloc C89 local and refcount order: PASS") text = check("_PyObject_Dump", ( "PyTypeObject *type;", "PyGILState_STATE gil;", "PyObject *error_type, *error_value, *error_traceback;", "if (_PyObject_IsFreed(op))", "type = Py_TYPE(op);", "gil = PyGILState_Ensure();", "PyErr_Fetch(&error_type, &error_value, &error_traceback);", ), "_PyObject_Dump must hoist locals without changing diagnostics or exception preservation") assert "PyTypeObject *type =" not in text and "PyGILState_STATE gil =" not in text print("object _PyObject_Dump C89 locals and exception preservation: PASS") text = check("PyObject_Repr", ( "PyObject *res;", "PyThreadState *tstate;", "if (PyErr_CheckSignals())", "tstate = _PyThreadState_GET();", ), "PyObject_Repr must hoist tstate while preserving signal-check order") assert "PyThreadState *tstate =" not in text print("object PyObject_Repr C89 local and signal-check order: PASS")