Fix the type value of 'bpy.types.*.bl_rna'
The type of an RNA types "bl_rna" should be `bpy.types.Struct`, it was being set to the type it represented so: `type(bpy.types.Object.bl_rna) == bpy.types.Object` which wasn't correct. Ref !126877 Co-authored-by: Bastien Montagne <bastien@blender.org>
This commit is contained in:
@@ -90,6 +90,11 @@
|
|||||||
|
|
||||||
BPy_StructRNA *bpy_context_module = nullptr; /* for fast access */
|
BPy_StructRNA *bpy_context_module = nullptr; /* for fast access */
|
||||||
|
|
||||||
|
static PyObject *pyrna_struct_CreatePyObject_from_type(PointerRNA *ptr,
|
||||||
|
PyTypeObject *tp,
|
||||||
|
void **instance);
|
||||||
|
|
||||||
|
static PyObject *pyrna_srna_Subtype(StructRNA *srna);
|
||||||
static PyObject *pyrna_struct_Subtype(PointerRNA *ptr);
|
static PyObject *pyrna_struct_Subtype(PointerRNA *ptr);
|
||||||
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
|
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
|
||||||
|
|
||||||
@@ -7347,8 +7352,6 @@ static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *se
|
|||||||
|
|
||||||
static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
|
static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
|
||||||
{
|
{
|
||||||
PyObject *item;
|
|
||||||
|
|
||||||
Py_INCREF(newclass);
|
Py_INCREF(newclass);
|
||||||
|
|
||||||
if (PyObject *oldclass = static_cast<PyObject *>(RNA_struct_py_type_get(srna))) {
|
if (PyObject *oldclass = static_cast<PyObject *>(RNA_struct_py_type_get(srna))) {
|
||||||
@@ -7362,12 +7365,25 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
|
|||||||
|
|
||||||
/* Python deals with the circular reference. */
|
/* Python deals with the circular reference. */
|
||||||
PointerRNA ptr = RNA_pointer_create(nullptr, &RNA_Struct, srna);
|
PointerRNA ptr = RNA_pointer_create(nullptr, &RNA_Struct, srna);
|
||||||
item = pyrna_struct_CreatePyObject(&ptr);
|
|
||||||
|
|
||||||
/* NOTE: must set the class not the __dict__ else the internal slots are not updated correctly.
|
/* NOTE: using `pyrna_struct_CreatePyObject(&ptr)` is close to what is needed,
|
||||||
*/
|
* however the it isn't correct because the result of:
|
||||||
PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item);
|
* `type(bpy.types.Object.bl_rna) == bpy.types.Object`.
|
||||||
Py_DECREF(item);
|
* In this case the type of `bl_rna` should be `bpy.types.Struct`.
|
||||||
|
* This is passed in explicitly, while #pyrna_struct_CreatePyObject could
|
||||||
|
* take this as an argument it's such a corner case that using a lower level
|
||||||
|
* function that takes the type is preferable. */
|
||||||
|
{
|
||||||
|
BLI_assert(RNA_struct_instance(&ptr) == nullptr);
|
||||||
|
PyTypeObject *tp = (PyTypeObject *)pyrna_srna_Subtype(&RNA_Struct);
|
||||||
|
PyObject *item = pyrna_struct_CreatePyObject_from_type(&ptr, tp, nullptr);
|
||||||
|
Py_DECREF(tp); /* `srna` owns, can't hold a reference. */
|
||||||
|
|
||||||
|
/* NOTE: must set the class not the `__dict__`
|
||||||
|
* else the internal slots are not updated correctly. */
|
||||||
|
PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item);
|
||||||
|
Py_DECREF(item);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add `staticmethod` and `classmethod` functions. */
|
/* Add `staticmethod` and `classmethod` functions. */
|
||||||
{
|
{
|
||||||
@@ -7392,8 +7408,6 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
|
|||||||
/* Done with RNA instance. */
|
/* Done with RNA instance. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *pyrna_srna_Subtype(StructRNA *srna);
|
|
||||||
|
|
||||||
/* Return a borrowed reference. */
|
/* Return a borrowed reference. */
|
||||||
static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dict)
|
static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dict)
|
||||||
{
|
{
|
||||||
@@ -7604,38 +7618,16 @@ static PyObject *pyrna_struct_Subtype(PointerRNA *ptr)
|
|||||||
|
|
||||||
/*-----------------------CreatePyObject---------------------------------*/
|
/*-----------------------CreatePyObject---------------------------------*/
|
||||||
|
|
||||||
PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
|
/**
|
||||||
|
* A lower level version of #pyrna_struct_CreatePyObject,
|
||||||
|
* use this when type (`tp`) needs to be set to a non-standard value.
|
||||||
|
*/
|
||||||
|
static PyObject *pyrna_struct_CreatePyObject_from_type(PointerRNA *ptr,
|
||||||
|
PyTypeObject *tp,
|
||||||
|
void **instance)
|
||||||
{
|
{
|
||||||
BPy_StructRNA *pyrna = nullptr;
|
BPy_StructRNA *pyrna = nullptr;
|
||||||
|
if (tp) {
|
||||||
/* NOTE: don't rely on this to return None since nullptr data with a valid type can often crash.
|
|
||||||
*/
|
|
||||||
if (ptr->data == nullptr && ptr->type == nullptr) { /* Operator RNA has nullptr data. */
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* New in 2.8x, since not many types support instancing
|
|
||||||
* we may want to use a flag to avoid looping over all classes. - campbell */
|
|
||||||
void **instance = ptr->data ? RNA_struct_instance(ptr) : nullptr;
|
|
||||||
if (instance && *instance) {
|
|
||||||
pyrna = static_cast<BPy_StructRNA *>(*instance);
|
|
||||||
|
|
||||||
/* Refine may have changed types after the first instance was created. */
|
|
||||||
if (ptr->type == pyrna->ptr.type) {
|
|
||||||
Py_INCREF(pyrna);
|
|
||||||
return (PyObject *)pyrna;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Existing users will need to use 'type_recast' method. */
|
|
||||||
Py_DECREF(pyrna);
|
|
||||||
*instance = nullptr;
|
|
||||||
/* Continue as if no instance was made. */
|
|
||||||
#if 0 /* No need to assign, will be written to next... */
|
|
||||||
pyrna = nullptr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr)) {
|
|
||||||
pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0);
|
pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0);
|
||||||
#ifdef USE_PYRNA_STRUCT_REFERENCE
|
#ifdef USE_PYRNA_STRUCT_REFERENCE
|
||||||
/* #PyType_GenericAlloc will have set tracking.
|
/* #PyType_GenericAlloc will have set tracking.
|
||||||
@@ -7644,7 +7636,6 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
|
|||||||
PyObject_GC_UnTrack(pyrna);
|
PyObject_GC_UnTrack(pyrna);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Py_DECREF(tp); /* srna owns, can't hold a reference. */
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type));
|
CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type));
|
||||||
@@ -7698,6 +7689,43 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
|
|||||||
return (PyObject *)pyrna;
|
return (PyObject *)pyrna;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
BPy_StructRNA *pyrna = nullptr;
|
||||||
|
|
||||||
|
/* NOTE: don't rely on this to return None since nullptr data with a valid type can often crash.
|
||||||
|
*/
|
||||||
|
if (ptr->data == nullptr && ptr->type == nullptr) { /* Operator RNA has nullptr data. */
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New in 2.8x, since not many types support instancing
|
||||||
|
* we may want to use a flag to avoid looping over all classes. - campbell */
|
||||||
|
void **instance = ptr->data ? RNA_struct_instance(ptr) : nullptr;
|
||||||
|
if (instance && *instance) {
|
||||||
|
pyrna = static_cast<BPy_StructRNA *>(*instance);
|
||||||
|
|
||||||
|
/* Refine may have changed types after the first instance was created. */
|
||||||
|
if (ptr->type == pyrna->ptr.type) {
|
||||||
|
Py_INCREF(pyrna);
|
||||||
|
return (PyObject *)pyrna;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Existing users will need to use 'type_recast' method. */
|
||||||
|
Py_DECREF(pyrna);
|
||||||
|
*instance = nullptr;
|
||||||
|
/* Continue as if no instance was made. */
|
||||||
|
#if 0 /* No need to assign, will be written to next... */
|
||||||
|
pyrna = nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr);
|
||||||
|
pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject_from_type(ptr, tp, instance);
|
||||||
|
Py_XDECREF(tp); /* `srna` owns, can't hold a reference. */
|
||||||
|
return (PyObject *)pyrna;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *pyrna_struct_CreatePyObject_with_primitive_support(PointerRNA *ptr)
|
PyObject *pyrna_struct_CreatePyObject_with_primitive_support(PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
if (ptr->type == &RNA_PrimitiveString) {
|
if (ptr->type == &RNA_PrimitiveString) {
|
||||||
|
|||||||
Reference in New Issue
Block a user