Migrate static PyTypeObject to inline, delete PyTypeCache workarounds

All 27 PyTypeObject declarations in namespace mcrfpydef headers changed
from `static` to `inline` (C++17), ensuring a single global instance
across translation units. This fixes the root cause of stale-type-pointer
segfaults where only the McRFPy_API.cpp copy was PyType_Ready'd.

Replaced ~20 PyTypeCache call sites and 2 PyRAII::PyTypeRef lookups with
direct &mcrfpydef::Type references. Deleted PyTypeCache.h/.cpp,
PyObjectUtils.h, and PyRAII.h (all were workarounds for the static bug).

228/228 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
John McCardle 2026-02-16 20:58:09 -05:00
commit bb72040396
37 changed files with 74 additions and 600 deletions

View file

@ -4,7 +4,6 @@
#include "McRFPy_API.h"
#include "PythonObjectCache.h"
#include "PyAlignment.h"
#include "PyTypeCache.h" // Thread-safe cached Python types
#include "UIEntity.h"
#include "Profiler.h"
#include "PyFOV.h"
@ -1928,16 +1927,7 @@ PyObject* UIGrid::py_entities_in_radius(PyUIGridObject* self, PyObject* args, Py
PyObject* result = PyList_New(entities.size());
if (!result) return PyErr_NoMemory();
// Cache Entity type for efficiency
static PyTypeObject* cached_entity_type = nullptr;
if (!cached_entity_type) {
cached_entity_type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Entity");
if (!cached_entity_type) {
Py_DECREF(result);
return NULL;
}
Py_INCREF(cached_entity_type);
}
PyTypeObject* entity_type = &mcrfpydef::PyUIEntityType;
for (size_t i = 0; i < entities.size(); i++) {
auto& entity = entities[i];
@ -1948,7 +1938,7 @@ PyObject* UIGrid::py_entities_in_radius(PyUIGridObject* self, PyObject* args, Py
PyList_SET_ITEM(result, i, entity->self);
} else {
// Create new Python Entity wrapper
auto pyEntity = (PyUIEntityObject*)cached_entity_type->tp_alloc(cached_entity_type, 0);
auto pyEntity = (PyUIEntityObject*)entity_type->tp_alloc(entity_type, 0);
if (!pyEntity) {
Py_DECREF(result);
return PyErr_NoMemory();