bugfix: segfault in Grid.at() due to internal types not exported to module

After #184/#189 made GridPoint and GridPointState internal-only types,
code using PyObject_GetAttrString(mcrf_module, "GridPoint") would get
NULL and crash when dereferencing.

Fixed by using the type directly via &mcrfpydef::PyUIGridPointType
instead of looking it up in the module.

Affected functions:
- UIGrid::py_at()
- UIGridPointState::get_point()
- UIEntity::at()
- UIGridPointState_to_PyObject()

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John McCardle 2026-01-06 04:38:56 -05:00
commit a4c2c04343
3 changed files with 8 additions and 16 deletions

View file

@ -122,9 +122,9 @@ PyObject* UIEntity::at(PyUIEntityObject* self, PyObject* args, PyObject* kwds) {
return NULL; return NULL;
} }
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "GridPointState"); // Use type directly since GridPointState is internal-only (not exported to module)
auto type = &mcrfpydef::PyUIGridPointStateType;
auto obj = (PyUIGridPointStateObject*)type->tp_alloc(type, 0); auto obj = (PyUIGridPointStateObject*)type->tp_alloc(type, 0);
Py_DECREF(type);
obj->data = &(self->data->gridstate[y * self->data->grid->grid_x + x]); obj->data = &(self->data->gridstate[y * self->data->grid->grid_x + x]);
obj->grid = self->data->grid; obj->grid = self->data->grid;
obj->entity = self->data; obj->entity = self->data;
@ -320,14 +320,10 @@ sf::Vector2i PyObject_to_sfVector2i(PyObject* obj) {
PyObject* UIGridPointState_to_PyObject(const UIGridPointState& state) { PyObject* UIGridPointState_to_PyObject(const UIGridPointState& state) {
// Create a new GridPointState Python object (detached - no grid/entity context) // Create a new GridPointState Python object (detached - no grid/entity context)
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "GridPointState"); // Use type directly since GridPointState is internal-only (not exported to module)
if (!type) { auto type = &mcrfpydef::PyUIGridPointStateType;
return NULL;
}
auto obj = (PyUIGridPointStateObject*)type->tp_alloc(type, 0); auto obj = (PyUIGridPointStateObject*)type->tp_alloc(type, 0);
if (!obj) { if (!obj) {
Py_DECREF(type);
return NULL; return NULL;
} }
@ -342,7 +338,6 @@ PyObject* UIGridPointState_to_PyObject(const UIGridPointState& state) {
obj->x = -1; obj->x = -1;
obj->y = -1; obj->y = -1;
Py_DECREF(type);
return (PyObject*)obj; return (PyObject*)obj;
} }

View file

@ -1182,8 +1182,8 @@ PyObject* UIGrid::py_at(PyUIGridObject* self, PyObject* args, PyObject* kwds)
return NULL; return NULL;
} }
//PyUIGridPointObject* obj = (PyUIGridPointObject*)((&PyUIGridPointType)->tp_alloc(&PyUIGridPointType, 0)); // Use the type directly since GridPoint is internal-only (not exported to module)
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "GridPoint"); auto type = &mcrfpydef::PyUIGridPointType;
auto obj = (PyUIGridPointObject*)type->tp_alloc(type, 0); auto obj = (PyUIGridPointObject*)type->tp_alloc(type, 0);
//auto target = std::static_pointer_cast<UIEntity>(target); //auto target = std::static_pointer_cast<UIEntity>(target);
// #123 - Use at() method to route through chunks for large grids // #123 - Use at() method to route through chunks for large grids

View file

@ -201,12 +201,9 @@ PyObject* UIGridPointState::get_point(PyUIGridPointStateObject* self, void* clos
return NULL; return NULL;
} }
// Return the GridPoint at this position // Return the GridPoint at this position (use type directly since it's internal-only)
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "GridPoint"); auto type = &mcrfpydef::PyUIGridPointType;
if (!type) return NULL;
auto obj = (PyUIGridPointObject*)type->tp_alloc(type, 0); auto obj = (PyUIGridPointObject*)type->tp_alloc(type, 0);
Py_DECREF(type);
if (!obj) return NULL; if (!obj) return NULL;
// Get the GridPoint from the grid // Get the GridPoint from the grid