diff options
Diffstat (limited to 'source/blender/python/mathutils/mathutils.c')
-rw-r--r-- | source/blender/python/mathutils/mathutils.c | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c index dcb6d7f3bc6..ef5339c3aa3 100644 --- a/source/blender/python/mathutils/mathutils.c +++ b/source/blender/python/mathutils/mathutils.c @@ -47,8 +47,7 @@ static int mathutils_array_parse_fast(float *array, i = size; do { i--; - if (((array[i] = PyFloat_AsDouble((item = value_fast_items[i]))) == -1.0f) && - PyErr_Occurred()) { + if (((array[i] = PyFloat_AsDouble(item = value_fast_items[i])) == -1.0f) && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "%.200s: sequence index %d expected a number, " "found '%.200s' type, ", @@ -317,7 +316,7 @@ int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const i = size; while (i > 0) { i--; - if (((array[i] = PyC_Long_AsI32((item = value_fast_items[i]))) == -1) && PyErr_Occurred()) { + if (((array[i] = PyC_Long_AsI32(item = value_fast_items[i])) == -1) && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "%.200s: sequence index %d expected an int", error_prefix, i); size = -1; break; @@ -698,6 +697,18 @@ int BaseMathObject_clear(BaseMathObject *self) return 0; } +/** Only to validate assumptions when debugging. */ +#ifndef NDEBUG +static bool BaseMathObject_is_tracked(BaseMathObject *self) +{ + PyObject *cb_user = self->cb_user; + self->cb_user = (void *)(uintptr_t)-1; + bool is_tracked = PyObject_GC_IsTracked((PyObject *)self); + self->cb_user = cb_user; + return is_tracked; +} +#endif /* NDEBUG */ + void BaseMathObject_dealloc(BaseMathObject *self) { /* only free non wrapped */ @@ -706,11 +717,46 @@ void BaseMathObject_dealloc(BaseMathObject *self) } if (self->cb_user) { + BLI_assert(BaseMathObject_is_tracked(self) == true); PyObject_GC_UnTrack(self); BaseMathObject_clear(self); } + else if (!BaseMathObject_CheckExact(self)) { + /* Sub-classed types get an extra track (in Pythons internal `subtype_dealloc` function). */ + BLI_assert(BaseMathObject_is_tracked(self) == true); + PyObject_GC_UnTrack(self); + BLI_assert(BaseMathObject_is_tracked(self) == false); + } + + Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); /* breaks sub-types. */ +} + +int BaseMathObject_is_gc(BaseMathObject *self) +{ + return self->cb_user != NULL; +} + +PyObject *_BaseMathObject_new_impl(PyTypeObject *root_type, PyTypeObject *base_type) +{ + PyObject *obj; + if (ELEM(base_type, NULL, root_type)) { + obj = _PyObject_GC_New(root_type); + if (obj) { + BLI_assert(BaseMathObject_is_tracked((BaseMathObject *)obj) == false); + } + } + else { + /* Calls Generic allocation function which always tracks + * (because `root_type` is flagged for GC). */ + obj = base_type->tp_alloc(base_type, 0); + if (obj) { + BLI_assert(BaseMathObject_is_tracked((BaseMathObject *)obj) == true); + PyObject_GC_UnTrack(obj); + BLI_assert(BaseMathObject_is_tracked((BaseMathObject *)obj) == false); + } + } - Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); /* breaks subtypes. */ + return obj; } /*----------------------------MODULE INIT-------------------------*/ @@ -720,14 +766,14 @@ static struct PyMethodDef M_Mathutils_methods[] = { static struct PyModuleDef M_Mathutils_module_def = { PyModuleDef_HEAD_INIT, - "mathutils", /* m_name */ - M_Mathutils_doc, /* m_doc */ - 0, /* m_size */ - M_Mathutils_methods, /* m_methods */ - NULL, /* m_slots */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ + /*m_name*/ "mathutils", + /*m_doc*/ M_Mathutils_doc, + /*m_size*/ 0, + /*m_methods*/ M_Mathutils_methods, + /*m_slots*/ NULL, + /*m_traverse*/ NULL, + /*m_clear*/ NULL, + /*m_free*/ NULL, }; /* submodules only */ |