RNA: Make the PointerRNA struct non-trivial.

For now, PointerRNA is made non-trivial by giving explicit default
values to its members.

Besides of BPY python binding code, the change is relatively trivial.
The main change (besides the creation/deletion part) is the replacement
of `memset` by zero-initialized assignment (using `{}`).

makesrna required changes are quite small too.

The big piece of this PR is the refactor of the BPY RNA code.

It essentially brings back allocation and deletion of the BPy_StructRNA,
BPy_Pointer etc. python objects into 'cannonical process', using `__new__`,
and `__init__` callbacks (and there matching CAPI functions).

Existing code was doing very low-level manipulations to create these
data, which is not really easy to understand, and AFAICT incompatible
with handling C++ data that needs to be constructed and destructed.

Unfortunately, similar change in destruction code (using `__del__` and
matching `tp_finalize` CAPI callback) is not possible, because of technical
low-level implementation details in CPython (see [1] for details).

`std::optional` pointer management is used to encapsulate PointerRNA
data. This allows to keep control on _when_ actual RNA creation is done,
and to have a safe destruction in `tp_dealloc` callbacks.

Note that a critical change in Blender's Python API will be that classes
inherinting from `bpy_struct` etc. will now have to properly call the
base class `__new__` and/or `__init__`if they define them.

Implements #122431.

[1] https://discuss.python.org/t/cpython-usage-of-tp-finalize-in-c-defined-static-types-with-no-custom-tp-dealloc/64100
This commit is contained in:
Bastien Montagne
2024-10-30 15:08:37 +01:00
committed by Bastien Montagne
parent 1b130f651a
commit 1dbe94c8ac
21 changed files with 1246 additions and 672 deletions

View File

@@ -49,7 +49,8 @@ class CyclesRender(bpy.types.RenderEngine):
bl_use_custom_freestyle = True
bl_use_alembic_procedural = True
def __init__(self):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.session = None
def __del__(self):

View File

@@ -1344,7 +1344,8 @@ class HydraRenderEngine(RenderEngine):
bl_use_shading_nodes_custom = False
bl_delegate_id = 'HdStormRendererPlugin'
def __init__(self):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.engine_ptr = None
def __del__(self):

View File

@@ -33,7 +33,8 @@ class NODE_OT_connect_to_output(Operator, NodeEditorBase):
default=True,
)
def __init__(self):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.shader_output_idname = ""
@classmethod

View File

@@ -218,11 +218,11 @@ static PyObject *Freestyle_evaluateColorRamp(PyObject * /*self*/, PyObject *args
if (!PyArg_ParseTuple(args, "O!f", &pyrna_struct_Type, &py_srna, &in)) {
return nullptr;
}
if (!RNA_struct_is_a(py_srna->ptr.type, &RNA_ColorRamp)) {
if (!RNA_struct_is_a(py_srna->ptr->type, &RNA_ColorRamp)) {
PyErr_SetString(PyExc_TypeError, "1st argument is not a ColorRamp object");
return nullptr;
}
coba = (ColorBand *)py_srna->ptr.data;
coba = (ColorBand *)py_srna->ptr->data;
if (!BKE_colorband_evaluate(coba, in, out)) {
PyErr_SetString(PyExc_ValueError, "failed to evaluate the color ramp");
return nullptr;
@@ -258,7 +258,7 @@ static PyObject *Freestyle_evaluateCurveMappingF(PyObject * /*self*/, PyObject *
if (!PyArg_ParseTuple(args, "O!if", &pyrna_struct_Type, &py_srna, &cur, &value)) {
return nullptr;
}
if (!RNA_struct_is_a(py_srna->ptr.type, &RNA_CurveMapping)) {
if (!RNA_struct_is_a(py_srna->ptr->type, &RNA_CurveMapping)) {
PyErr_SetString(PyExc_TypeError, "1st argument is not a CurveMapping object");
return nullptr;
}
@@ -266,7 +266,7 @@ static PyObject *Freestyle_evaluateCurveMappingF(PyObject * /*self*/, PyObject *
PyErr_SetString(PyExc_ValueError, "2nd argument is out of range");
return nullptr;
}
cumap = (CurveMapping *)py_srna->ptr.data;
cumap = (CurveMapping *)py_srna->ptr->data;
BKE_curvemapping_init(cumap);
/* disable extrapolation if enabled */
if (cumap->flag & CUMA_EXTEND_EXTRAPOLATE) {

View File

@@ -631,7 +631,7 @@ void RNA_collection_clear(PointerRNA *ptr, const char *name);
#define RNA_STRUCT_BEGIN(sptr, prop) \
{ \
CollectionPropertyIterator rna_macro_iter; \
CollectionPropertyIterator rna_macro_iter{}; \
for (RNA_property_collection_begin( \
sptr, RNA_struct_iterator_property((sptr)->type), &rna_macro_iter); \
rna_macro_iter.valid; \

View File

@@ -37,12 +37,12 @@ struct bContext;
* the properties and validate them. */
struct PointerRNA {
ID *owner_id;
StructRNA *type;
void *data;
ID *owner_id = nullptr;
StructRNA *type = nullptr;
void *data = nullptr;
};
constexpr PointerRNA PointerRNA_NULL{nullptr, nullptr, nullptr};
extern const PointerRNA PointerRNA_NULL;
struct PropertyPointerRNA {
PointerRNA ptr;
@@ -451,6 +451,7 @@ struct CollectionPropertyIterator {
PointerRNA builtin_parent;
PropertyRNA *prop;
union {
/* Keep biggest object first in the union, for zero-initialization to work properly. */
ArrayIterator array;
ListBaseIterator listbase;
CountIterator count;

View File

@@ -1619,7 +1619,7 @@ static char *rna_def_property_begin_func(
rna_print_data_get(f, dp);
}
fprintf(f, "\n memset(iter, 0, sizeof(*iter));\n");
fprintf(f, "\n *iter = {};\n");
fprintf(f, " iter->parent = *ptr;\n");
fprintf(f, " iter->prop = &rna_%s_%s;\n", srna->identifier, prop->identifier);
@@ -3417,17 +3417,28 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
if (func->c_ret) {
dparm = rna_find_parameter_def(func->c_ret);
ptrstr = (((dparm->prop->type == PROP_POINTER) &&
!(dparm->prop->flag_parameter & PARM_RNAPTR)) ||
(dparm->prop->arraydimension)) ?
"*" :
"";
fprintf(f,
"\t*((%s%s %s*)_retdata) = %s;\n",
rna_type_struct(dparm->prop),
rna_parameter_type_name(dparm->prop),
ptrstr,
func->c_ret->identifier);
if ((dparm->prop->type == PROP_POINTER) && (dparm->prop->flag_parameter & PARM_RNAPTR) &&
(dparm->prop->flag & PROP_THICK_WRAP))
{
const char *parameter_type_name = rna_parameter_type_name(dparm->prop);
fprintf(f,
"\t*reinterpret_cast<%s *>(_retdata) = %s;\n",
parameter_type_name,
func->c_ret->identifier);
}
else {
ptrstr = (((dparm->prop->type == PROP_POINTER) &&
!(dparm->prop->flag_parameter & PARM_RNAPTR)) ||
(dparm->prop->arraydimension)) ?
"*" :
"";
fprintf(f,
"\t*((%s%s %s*)_retdata) = %s;\n",
rna_type_struct(dparm->prop),
rna_parameter_type_name(dparm->prop),
ptrstr,
func->c_ret->identifier);
}
}
}
@@ -5188,7 +5199,7 @@ static const char *cpp_classes =
" } \\\n"
" sname##_##identifier##_end(&iter); \\\n"
" if (!found) { \\\n"
" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
" *r_ptr = {}; \\\n"
" } \\\n"
" return found; \\\n"
" } \n"
@@ -5198,7 +5209,7 @@ static const char *cpp_classes =
" { \\\n"
" bool found = sname##_##identifier##_lookup_int(ptr, key, r_ptr); \\\n"
" if (!found) { \\\n"
" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
" *r_ptr = {}; \\\n"
" } \\\n"
" return found; \\\n"
" } \n"
@@ -5227,7 +5238,7 @@ static const char *cpp_classes =
" } \\\n"
" sname##_##identifier##_end(&iter); \\\n"
" if (!found) { \\\n"
" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
" *r_ptr = {}; \\\n"
" } \\\n"
" return found; \\\n"
" } \n"
@@ -5237,7 +5248,7 @@ static const char *cpp_classes =
" { \\\n"
" bool found = sname##_##identifier##_lookup_string(ptr, key, r_ptr); \\\n"
" if (!found) { \\\n"
" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
" *r_ptr = {}; \\\n"
" } \\\n"
" return found; \\\n"
" } \n"

View File

@@ -10,6 +10,7 @@
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <new>
#include <sstream>
#include <fmt/format.h>
@@ -75,6 +76,9 @@ static CLG_LogRef LOG = {"rna.access"};
/* Init/Exit */
/* NOTE: Initializing this object here is fine for now, as it should not allocate any memory. */
extern const PointerRNA PointerRNA_NULL = {};
void RNA_init()
{
StructRNA *srna;
@@ -218,7 +222,7 @@ static void rna_pointer_inherit_id(const StructRNA *type,
PointerRNA RNA_blender_rna_pointer_create()
{
PointerRNA ptr;
PointerRNA ptr = {};
ptr.owner_id = nullptr;
ptr.type = &RNA_BlenderRNA;
ptr.data = &BLENDER_RNA;
@@ -6290,6 +6294,10 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms,
data_alloc->array_tot = 0;
data_alloc->array = nullptr;
}
else if ((parm->flag_parameter & PARM_RNAPTR) && (parm->flag & PROP_THICK_WRAP)) {
BLI_assert(parm->type == PROP_POINTER);
new (static_cast<PointerRNA *>(data)) PointerRNA();
}
if (!(parm->flag_parameter & PARM_REQUIRED) && !(parm->flag & PROP_DYNAMIC)) {
switch (parm->type) {
@@ -6351,23 +6359,28 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms,
void RNA_parameter_list_free(ParameterList *parms)
{
PropertyRNA *parm;
int tot;
parm = static_cast<PropertyRNA *>(parms->func->cont.properties.first);
for (tot = 0; parm; parm = parm->next) {
void *data = parms->data;
for (; parm; parm = parm->next) {
if (parm->type == PROP_COLLECTION) {
BLI_freelistN((ListBase *)((char *)parms->data + tot));
BLI_freelistN(static_cast<ListBase *>(data));
}
else if ((parm->flag_parameter & PARM_RNAPTR) && (parm->flag & PROP_THICK_WRAP)) {
BLI_assert(parm->type == PROP_POINTER);
PointerRNA *ptr = static_cast<PointerRNA *>(data);
/* #RNA_parameter_list_create ensures that 'thick wrap' PointerRNA parameters are
* constructed. */
ptr->~PointerRNA();
}
else if (parm->flag & PROP_DYNAMIC) {
/* for dynamic arrays and strings, data is a pointer to an array */
ParameterDynAlloc *data_alloc = static_cast<ParameterDynAlloc *>(
(void *)(((char *)parms->data) + tot));
ParameterDynAlloc *data_alloc = static_cast<ParameterDynAlloc *>(data);
if (data_alloc->array) {
MEM_freeN(data_alloc->array);
}
}
tot += rna_parameter_size_pad(rna_parameter_size(parm));
data = static_cast<char *>(data) + rna_parameter_size_pad(rna_parameter_size(parm));
}
MEM_freeN(parms->data);
@@ -6507,6 +6520,14 @@ void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, const void *valu
data_alloc->array = MEM_mallocN(size, __func__);
memcpy(data_alloc->array, value, size);
}
else if ((parm->flag_parameter & PARM_RNAPTR) && (parm->flag & PROP_THICK_WRAP)) {
BLI_assert(parm->type == PROP_POINTER);
BLI_assert(iter.size == sizeof(PointerRNA));
PointerRNA *ptr = static_cast<PointerRNA *>(iter.data);
/* #RNA_parameter_list_create ensures that 'thick wrap' PointerRNA parameters are
* constructed. */
*ptr = PointerRNA(*static_cast<const PointerRNA *>(value));
}
else {
memcpy(iter.data, value, iter.size);
}

View File

@@ -229,7 +229,7 @@ static void bpy_pydriver_namespace_update_depsgraph(Depsgraph *depsgraph)
}
if ((g_pydriver_state_prev.depsgraph == nullptr) ||
(depsgraph != g_pydriver_state_prev.depsgraph->ptr.data))
(depsgraph != g_pydriver_state_prev.depsgraph->ptr->data))
{
PyObject *item = bpy_pydriver_depsgraph_as_pyobject(depsgraph);
PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_depsgraph, item);

View File

@@ -240,12 +240,12 @@ void BPY_modules_update()
bContext *BPY_context_get()
{
return static_cast<bContext *>(bpy_context_module->ptr.data);
return static_cast<bContext *>(bpy_context_module->ptr->data);
}
void BPY_context_set(bContext *C)
{
bpy_context_module->ptr.data = (void *)C;
bpy_context_module->ptr->data = (void *)C;
}
#ifdef WITH_FLUID
@@ -754,7 +754,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
done = true;
}
else if (BPy_StructRNA_Check(item)) {
ptr = &(((BPy_StructRNA *)item)->ptr);
ptr = &reinterpret_cast<BPy_StructRNA *>(item)->ptr.value();
// result->ptr = ((BPy_StructRNA *)item)->ptr;
CTX_data_pointer_set_ptr(result, ptr);
@@ -776,7 +776,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
PyObject *list_item = seq_fast_items[i];
if (BPy_StructRNA_Check(list_item)) {
ptr = &(((BPy_StructRNA *)list_item)->ptr);
ptr = &reinterpret_cast<BPy_StructRNA *>(list_item)->ptr.value();
CTX_data_list_add_ptr(result, ptr);
}
else {

View File

@@ -185,7 +185,7 @@ PyDoc_STRVAR(
static PyObject *bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *kw)
{
Main *bmain_base = CTX_data_main(BPY_context_get());
Main *bmain = static_cast<Main *>(self->ptr.data); /* Typically #G_MAIN */
Main *bmain = static_cast<Main *>(self->ptr->data); /* Typically #G_MAIN */
BPy_Library *ret;
PyC_UnicodeAsBytesAndSize_Data filepath_data = {nullptr};
bool is_rel = false, is_link = false, use_assets_only = false;

View File

@@ -119,7 +119,7 @@ static PyObject *bpy_lib_write(BPy_PropertyRNA *self, PyObject *args, PyObject *
return nullptr;
}
Main *bmain_src = static_cast<Main *>(self->ptr.data); /* Typically #G_MAIN */
Main *bmain_src = static_cast<Main *>(self->ptr->data); /* Typically #G_MAIN */
int write_flags = 0;
if (use_compress) {

View File

@@ -71,14 +71,14 @@ static int py_msgbus_rna_key_from_py(PyObject *py_sub,
if (BPy_PropertyRNA_Check(py_sub)) {
BPy_PropertyRNA *data_prop = (BPy_PropertyRNA *)py_sub;
PYRNA_PROP_CHECK_INT(data_prop);
msg_key_params->ptr = data_prop->ptr;
msg_key_params->ptr = *data_prop->ptr;
msg_key_params->prop = data_prop->prop;
}
else if (BPy_StructRNA_Check(py_sub)) {
/* NOTE: this isn't typically used since we don't edit structs directly. */
BPy_StructRNA *data_srna = (BPy_StructRNA *)py_sub;
PYRNA_STRUCT_CHECK_INT(data_srna);
msg_key_params->ptr = data_srna->ptr;
msg_key_params->ptr = *data_srna->ptr;
}
/* TODO: property / type, not instance. */
else if (PyType_Check(py_sub)) {

View File

@@ -16,6 +16,8 @@
#include <cfloat> /* FLT_MIN/MAX */
#include <cstddef>
#include <new>
#include <optional>
#include "RNA_path.hh"
#include "RNA_types.hh"
@@ -90,6 +92,35 @@
BPy_StructRNA *bpy_context_module = nullptr; /* for fast access */
/**
* 'Name' identifier for PyCapsule objects used internally by `bpy_rna.cc` to pass a #PointerRNA
* pointer as argument when creating #BPy_StructRNA objects.
*/
static const char *BPy_capsule_PointerRNA_identifier = "BPy_PointerRNA_PyCapsule";
/** Basic container for a PropertyRNA and its PointerRNA. */
struct BPy_PropertyPointerRNA_Reference {
const PointerRNA *ptr;
PropertyRNA *prop;
};
/**
* 'Name' identifier for PyCapsule objects used internally by `bpy_rna.cc` to pass a
* #BPy_PropertyPointerRNA_Reference pointer as argument when creating #BPy_PropertyRNA and similar
* objects.
*/
static const char *BPy_PropertyPointerRNA_capsule_identifier = "BPy_PropertyPointerRNA_PyCapsule";
/** Basic container for a FunctionRNA and its PointerRNA. */
struct BPy_FunctionPointerRNA_Reference {
const PointerRNA *ptr;
FunctionRNA *func;
};
/**
* 'Name' identifier for PyCapsule objects used internally by `bpy_rna.cc` to pass a
* #BPy_FunctionPointerRNA_Reference pointer as argument when creating #BPy_FunctionRNA objects.
*/
static const char *BPy_FunctionPointerRNA_capsule_identifier = "BPy_FunctionPointerRNA_PyCapsule";
static PyObject *pyrna_struct_CreatePyObject_from_type(const PointerRNA *ptr,
PyTypeObject *tp,
void **instance);
@@ -111,7 +142,7 @@ static StructRNA *srna_from_ptr(PointerRNA *ptr);
int pyrna_struct_validity_check_only(const BPy_StructRNA *pysrna)
{
if (pysrna->ptr.type) {
if (pysrna->ptr->type) {
return 0;
}
return -1;
@@ -125,7 +156,7 @@ void pyrna_struct_validity_exception_only(const BPy_StructRNA *pysrna)
int pyrna_struct_validity_check(const BPy_StructRNA *pysrna)
{
if (pysrna->ptr.type) {
if (pysrna->ptr->type) {
return 0;
}
pyrna_struct_validity_exception_only(pysrna);
@@ -134,7 +165,7 @@ int pyrna_struct_validity_check(const BPy_StructRNA *pysrna)
int pyrna_prop_validity_check(const BPy_PropertyRNA *self)
{
if (self->ptr.type) {
if (self->ptr->type) {
return 0;
}
PyErr_Format(PyExc_ReferenceError,
@@ -146,7 +177,7 @@ int pyrna_prop_validity_check(const BPy_PropertyRNA *self)
void pyrna_invalidate(BPy_DummyPointerRNA *self)
{
RNA_POINTER_INVALIDATE(&self->ptr);
RNA_POINTER_INVALIDATE(&self->ptr.value());
}
#ifdef USE_PYRNA_INVALIDATE_GC
@@ -173,7 +204,7 @@ static void id_release_gc(struct ID *id)
PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type))
{
BPy_DummyPointerRNA *ob_ptr = (BPy_DummyPointerRNA *)ob;
if (ob_ptr->ptr.owner_id == id) {
if (ob_ptr->ptr->owner_id == id) {
pyrna_invalidate(ob_ptr);
// printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
// i++;
@@ -433,13 +464,13 @@ static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
return -1;
}
RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
RNA_property_float_get_array(&self->ptr.value(), self->prop, bmo->data);
/* Euler order exception. */
if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
EulerObject *eul = (EulerObject *)bmo;
PropertyRNA *prop_eul_order = nullptr;
eul->order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order);
eul->order = pyrna_rotation_euler_order_get(&self->ptr.value(), eul->order, &prop_eul_order);
}
return 0;
@@ -457,42 +488,43 @@ static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
}
# ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
if (rna_disallow_writes && rna_id_write_error(&self->ptr.value(), nullptr)) {
return -1;
}
# endif /* USE_PEDANTIC_WRITE */
if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
if (!RNA_property_editable_flag(&self->ptr.value(), self->prop)) {
PyErr_Format(PyExc_AttributeError,
"bpy_prop \"%.200s.%.200s\" is read-only",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_property_identifier(self->prop));
return -1;
}
RNA_property_float_range(&self->ptr, self->prop, &min, &max);
RNA_property_float_range(&self->ptr.value(), self->prop, &min, &max);
if (min != -FLT_MAX || max != FLT_MAX) {
int i, len = RNA_property_array_length(&self->ptr, self->prop);
int i, len = RNA_property_array_length(&self->ptr.value(), self->prop);
for (i = 0; i < len; i++) {
CLAMP(bmo->data[i], min, max);
}
}
RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
RNA_property_float_set_array(&self->ptr.value(), self->prop, bmo->data);
if (RNA_property_update_check(self->prop)) {
RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
RNA_property_update(BPY_context_get(), &self->ptr.value(), self->prop);
}
/* Euler order exception. */
if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
EulerObject *eul = (EulerObject *)bmo;
PropertyRNA *prop_eul_order = nullptr;
const short order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order);
const short order = pyrna_rotation_euler_order_get(
&self->ptr.value(), eul->order, &prop_eul_order);
if (order != eul->order) {
RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order);
RNA_property_enum_set(&self->ptr.value(), prop_eul_order, eul->order);
if (RNA_property_update_check(prop_eul_order)) {
RNA_property_update(BPY_context_get(), &self->ptr, prop_eul_order);
RNA_property_update(BPY_context_get(), &self->ptr.value(), prop_eul_order);
}
}
}
@@ -509,7 +541,7 @@ static int mathutils_rna_vector_get_index(BaseMathObject *bmo, int /*subtype*/,
return -1;
}
bmo->data[index] = RNA_property_float_get_index(&self->ptr, self->prop, index);
bmo->data[index] = RNA_property_float_get_index(&self->ptr.value(), self->prop, index);
return 0;
}
@@ -524,24 +556,24 @@ static int mathutils_rna_vector_set_index(BaseMathObject *bmo, int /*subtype*/,
}
# ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
if (rna_disallow_writes && rna_id_write_error(&self->ptr.value(), nullptr)) {
return -1;
}
# endif /* USE_PEDANTIC_WRITE */
if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
if (!RNA_property_editable_flag(&self->ptr.value(), self->prop)) {
PyErr_Format(PyExc_AttributeError,
"bpy_prop \"%.200s.%.200s\" is read-only",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_property_identifier(self->prop));
return -1;
}
RNA_property_float_clamp(&self->ptr, self->prop, &bmo->data[index]);
RNA_property_float_set_index(&self->ptr, self->prop, index, bmo->data[index]);
RNA_property_float_clamp(&self->ptr.value(), self->prop, &bmo->data[index]);
RNA_property_float_set_index(&self->ptr.value(), self->prop, index, bmo->data[index]);
if (RNA_property_update_check(self->prop)) {
RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
RNA_property_update(BPY_context_get(), &self->ptr.value(), self->prop);
}
return 0;
@@ -568,7 +600,7 @@ static int mathutils_rna_matrix_get(BaseMathObject *bmo, int /*subtype*/)
return -1;
}
RNA_property_float_get_array(&self->ptr, self->prop, bmo->data);
RNA_property_float_get_array(&self->ptr.value(), self->prop, bmo->data);
return 0;
}
@@ -583,24 +615,24 @@ static int mathutils_rna_matrix_set(BaseMathObject *bmo, int /*subtype*/)
}
# ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
if (rna_disallow_writes && rna_id_write_error(&self->ptr.value(), nullptr)) {
return -1;
}
# endif /* USE_PEDANTIC_WRITE */
if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
if (!RNA_property_editable_flag(&self->ptr.value(), self->prop)) {
PyErr_Format(PyExc_AttributeError,
"bpy_prop \"%.200s.%.200s\" is read-only",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_property_identifier(self->prop));
return -1;
}
/* Can ignore clamping here. */
RNA_property_float_set_array(&self->ptr, self->prop, bmo->data);
RNA_property_float_set_array(&self->ptr.value(), self->prop, bmo->data);
if (RNA_property_update_check(self->prop)) {
RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
RNA_property_update(BPY_context_get(), &self->ptr.value(), self->prop);
}
return 0;
}
@@ -817,14 +849,15 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b)
{
return (((a->ptr.data == b->ptr.data) && (a->ptr.type == b->ptr.type)) ? 0 : -1);
return (((a->ptr->data == b->ptr->data) && (a->ptr->type == b->ptr->type)) ? 0 : -1);
}
static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b)
{
return (((a->prop == b->prop) && (a->ptr.data == b->ptr.data) && (a->ptr.type == b->ptr.type)) ?
0 :
-1);
return (
((a->prop == b->prop) && (a->ptr->data == b->ptr->data) && (a->ptr->type == b->ptr->type)) ?
0 :
-1);
}
static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
@@ -900,7 +933,7 @@ static PyObject *pyrna_struct_str(BPy_StructRNA *self)
return PyUnicode_FromFormat("<bpy_struct, %.200s invalid>", Py_TYPE(self)->tp_name);
}
ID *id = self->ptr.owner_id;
ID *id = self->ptr->owner_id;
if (id && id != DEG_get_original_id(id)) {
extra_info = ", evaluated";
}
@@ -909,26 +942,26 @@ static PyObject *pyrna_struct_str(BPy_StructRNA *self)
*
* Always include the pointer address since it can help identify unique data,
* or when data is re-allocated internally. */
name = RNA_struct_name_get_alloc(&self->ptr, nullptr, 0, nullptr);
name = RNA_struct_name_get_alloc(&self->ptr.value(), nullptr, 0, nullptr);
if (name) {
ret = PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\") at %p%s>",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
name,
self->ptr.data,
self->ptr->data,
extra_info);
MEM_freeN((void *)name);
return ret;
}
return PyUnicode_FromFormat("<bpy_struct, %.200s at %p%s>",
RNA_struct_identifier(self->ptr.type),
self->ptr.data,
RNA_struct_identifier(self->ptr->type),
self->ptr->data,
extra_info);
}
static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
{
ID *id = self->ptr.owner_id;
ID *id = self->ptr->owner_id;
PyObject *tmp_str;
PyObject *ret;
@@ -939,14 +972,14 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
tmp_str = PyUnicode_FromString(id->name + 2);
if (RNA_struct_is_ID(self->ptr.type) && (id->flag & ID_FLAG_EMBEDDED_DATA) == 0) {
if (RNA_struct_is_ID(self->ptr->type) && (id->flag & ID_FLAG_EMBEDDED_DATA) == 0) {
ret = PyUnicode_FromFormat(
"bpy.data.%s[%R]", BKE_idtype_idcode_to_name_plural(GS(id->name)), tmp_str);
}
else {
ID *real_id = nullptr;
const std::optional<std::string> path = RNA_path_from_real_ID_to_struct(
G_MAIN, &self->ptr, &real_id);
G_MAIN, &self->ptr.value(), &real_id);
if (path) {
/* 'real_id' may be nullptr in some cases, although the only valid one is evaluated data,
* which should have already been caught above.
@@ -966,7 +999,7 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
BKE_idtype_idcode_to_name_plural(GS(id->name)),
tmp_str,
RNA_struct_identifier(self->ptr.type));
RNA_struct_identifier(self->ptr->type));
}
}
else {
@@ -974,7 +1007,7 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s",
BKE_idtype_idcode_to_name_plural(GS(id->name)),
tmp_str,
RNA_struct_identifier(self->ptr.type));
RNA_struct_identifier(self->ptr->type));
}
}
@@ -1023,14 +1056,14 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
/* If a pointer, try to print name of pointer target too. */
if (type == PROP_POINTER) {
ptr = RNA_property_pointer_get(&self->ptr, self->prop);
ptr = RNA_property_pointer_get(&self->ptr.value(), self->prop);
name = RNA_struct_name_get_alloc(&ptr, nullptr, 0, nullptr);
if (name) {
ret = PyUnicode_FromFormat("<bpy_%.200s%.200s, %.200s.%.200s(\"%.200s\")>",
type_lower,
type_count,
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_property_identifier(self->prop),
name);
MEM_freeN((void *)name);
@@ -1039,7 +1072,7 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
}
if (type == PROP_COLLECTION) {
PointerRNA r_ptr;
if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
if (RNA_property_collection_type_get(&self->ptr.value(), self->prop, &r_ptr)) {
return PyUnicode_FromFormat(
"<bpy_%.200s%.200s, %.200s>", type_lower, type_count, RNA_struct_identifier(r_ptr.type));
}
@@ -1048,13 +1081,13 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
return PyUnicode_FromFormat("<bpy_%.200s%.200s, %.200s.%.200s>",
type_lower,
type_count,
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_property_identifier(self->prop));
}
static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, const int index)
{
ID *id = self->ptr.owner_id;
ID *id = self->ptr->owner_id;
PyObject *tmp_str;
PyObject *ret;
@@ -1071,7 +1104,7 @@ static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim,
* here. */
ID *real_id = nullptr;
const std::optional<std::string> path = RNA_path_from_real_ID_to_property_index(
G_MAIN, &self->ptr, self->prop, index_dim, index, &real_id);
G_MAIN, &self->ptr.value(), self->prop, index_dim, index, &real_id);
if (path) {
if (real_id != id) {
@@ -1112,24 +1145,24 @@ static PyObject *pyrna_func_repr(BPy_FunctionRNA *self)
{
return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>",
Py_TYPE(self)->tp_name,
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_function_identifier(self->func));
}
static Py_hash_t pyrna_struct_hash(BPy_StructRNA *self)
{
return _Py_HashPointer(self->ptr.data);
return _Py_HashPointer(self->ptr->data);
}
/* From Python's meth_hash v3.1.2. */
static long pyrna_prop_hash(BPy_PropertyRNA *self)
{
long x, y;
if (self->ptr.data == nullptr) {
if (self->ptr->data == nullptr) {
x = 0;
}
else {
x = _Py_HashPointer(self->ptr.data);
x = _Py_HashPointer(self->ptr->data);
if (x == -1) {
return -1;
}
@@ -1159,41 +1192,6 @@ static int pyrna_struct_clear(BPy_StructRNA *self)
}
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
/* Use our own dealloc so we can free a property if we use one. */
static void pyrna_struct_dealloc(BPy_StructRNA *self)
{
#ifdef PYRNA_FREE_SUPPORT
if (self->freeptr && self->ptr.data) {
IDP_FreeProperty(self->ptr.data);
self->ptr.data = nullptr;
}
#endif /* PYRNA_FREE_SUPPORT */
#ifdef USE_WEAKREFS
if (self->in_weakreflist != nullptr) {
PyObject_ClearWeakRefs((PyObject *)self);
}
#endif
#ifdef USE_PYRNA_STRUCT_REFERENCE
if (self->reference) {
PyObject_GC_UnTrack(self);
pyrna_struct_clear(self);
}
else {
PyTypeObject *base = Py_TYPE(self)->tp_base;
/* Python temporarily tracks these types when freeing, see Python bug 26617. */
if (base && PyType_IS_GC(base)) {
PyObject_GC_UnTrack(self);
}
BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
}
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
/* NOTE: for subclassed PyObjects calling PyObject_DEL() directly crashes. */
Py_TYPE(self)->tp_free(self);
}
#ifdef USE_PYRNA_STRUCT_REFERENCE
static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
{
@@ -1212,29 +1210,6 @@ static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
}
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
/* Use our own dealloc so we can free a property if we use one. */
static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
{
#ifdef USE_WEAKREFS
if (self->in_weakreflist != nullptr) {
PyObject_ClearWeakRefs((PyObject *)self);
}
#endif
/* NOTE: for subclassed PyObjects calling PyObject_DEL() directly crashes. */
Py_TYPE(self)->tp_free(self);
}
static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
{
#ifdef USE_WEAKREFS
if (self->in_weakreflist != nullptr) {
PyObject_ClearWeakRefs((PyObject *)self);
}
#endif
/* NOTE: for subclassed PyObjects calling PyObject_DEL() directly crashes. */
Py_TYPE(self)->tp_free(self);
}
static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
{
const EnumPropertyItem *item;
@@ -1555,10 +1530,21 @@ int pyrna_pydict_to_props(PointerRNA *ptr,
static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func)
{
BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *)PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
pyfunc->ptr = *ptr;
pyfunc->func = func;
return (PyObject *)pyfunc;
BPy_FunctionPointerRNA_Reference funcrna_ptr{ptr, func};
PyObject *pyfuncrna_ptr = PyCapsule_New(
&funcrna_ptr, BPy_FunctionPointerRNA_capsule_identifier, nullptr);
BPy_FunctionRNA *pyfunc = reinterpret_cast<BPy_FunctionRNA *>(
PyObject_CallOneArg(reinterpret_cast<PyObject *>(&pyrna_func_Type), pyfuncrna_ptr));
if (!pyfunc) {
PyErr_SetString(PyExc_MemoryError, "couldn't create bpy_func object");
return nullptr;
}
BLI_assert(pyfunc->ptr.has_value());
Py_DECREF(pyfuncrna_ptr);
return reinterpret_cast<PyObject *>(pyfunc);
}
static int pyrna_py_to_prop(
@@ -1843,7 +1829,7 @@ static int pyrna_py_to_prop(
*/
if ((ptr_type == &RNA_AnyType) && BPy_StructRNA_Check(value)) {
const StructRNA *base_type = RNA_struct_base_child_of(
((const BPy_StructRNA *)value)->ptr.type, nullptr);
((const BPy_StructRNA *)value)->ptr->type, nullptr);
if (ELEM(base_type, &RNA_Operator, &RNA_Gizmo)) {
value = PyObject_GetAttr(value, bpy_intern_str_properties);
value_new = value;
@@ -1868,7 +1854,8 @@ static int pyrna_py_to_prop(
if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* Ok to ignore idprop collections. */
PointerRNA c_ptr;
BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value;
if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
if (RNA_property_collection_type_get(&value_prop->ptr.value(), value_prop->prop, &c_ptr))
{
value = pyrna_struct_CreatePyObject(&c_ptr);
value_new = value;
}
@@ -1912,7 +1899,7 @@ static int pyrna_py_to_prop(
}
param = (BPy_StructRNA *)value;
const ID *value_owner_id = ((BPy_StructRNA *)value)->ptr.owner_id;
const ID *value_owner_id = ((BPy_StructRNA *)value)->ptr->owner_id;
if (value_owner_id != nullptr) {
if ((flag & PROP_ID_SELF_CHECK) && (ptr->owner_id == value_owner_id)) {
PyErr_Format(PyExc_TypeError,
@@ -1945,10 +1932,10 @@ static int pyrna_py_to_prop(
if (flag_parameter & PARM_RNAPTR) {
if (flag & PROP_THICK_WRAP) {
if (param == nullptr) {
memset(data, 0, sizeof(PointerRNA));
*reinterpret_cast<PointerRNA *>(data) = {};
}
else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
*((PointerRNA *)data) = param->ptr;
else if (RNA_struct_is_a(param->ptr->type, ptr_type)) {
*reinterpret_cast<PointerRNA *>(data) = *param->ptr;
}
else {
raise_error = true;
@@ -1962,8 +1949,8 @@ static int pyrna_py_to_prop(
if (param == nullptr) {
*((void **)data) = nullptr;
}
else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
*((PointerRNA **)data) = &param->ptr;
else if (RNA_struct_is_a(param->ptr->type, ptr_type)) {
*((PointerRNA **)data) = &param->ptr.value();
}
else {
raise_error = true;
@@ -1973,8 +1960,8 @@ static int pyrna_py_to_prop(
else if (param == nullptr) {
*((void **)data) = nullptr;
}
else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
*((void **)data) = param->ptr.data;
else if (RNA_struct_is_a(param->ptr->type, ptr_type)) {
*((void **)data) = param->ptr->data;
}
else {
raise_error = true;
@@ -1982,11 +1969,11 @@ static int pyrna_py_to_prop(
}
else {
/* Data == nullptr, assign to RNA. */
if ((param == nullptr) || RNA_struct_is_a(param->ptr.type, ptr_type)) {
if ((param == nullptr) || RNA_struct_is_a(param->ptr->type, ptr_type)) {
ReportList reports;
BKE_reports_init(&reports, RPT_STORE);
RNA_property_pointer_set(
ptr, prop, (param == nullptr) ? PointerRNA_NULL : param->ptr, &reports);
ptr, prop, (param == nullptr) ? PointerRNA_NULL : *param->ptr, &reports);
const int err = BPy_reports_to_error(&reports, PyExc_RuntimeError, true);
if (err == -1) {
Py_XDECREF(value_new);
@@ -2010,7 +1997,7 @@ static int pyrna_py_to_prop(
RNA_struct_identifier(ptr->type),
RNA_property_identifier(prop),
RNA_struct_identifier(tmp.type),
RNA_struct_identifier(param->ptr.type));
RNA_struct_identifier(param->ptr->type));
}
Py_XDECREF(value_new);
return -1;
@@ -2120,13 +2107,13 @@ static int pyrna_py_to_prop(
static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
{
PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
return pyrna_py_from_array_index(self, &self->ptr.value(), self->prop, index);
}
static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, PyObject *value)
{
int ret = 0;
PointerRNA *ptr = &self->ptr;
PointerRNA *ptr = &self->ptr.value();
PropertyRNA *prop = self->prop;
const int totdim = RNA_property_array_dimension(ptr, prop, nullptr);
@@ -2134,7 +2121,8 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P
if (totdim > 1) {
// char error_str[512];
if (pyrna_py_to_array_index(
&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1)
&self->ptr.value(), self->prop, self->arraydim, self->arrayoffset, index, value, "") ==
-1)
{
/* Error is set. */
ret = -1;
@@ -2199,18 +2187,18 @@ static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
{
PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
if (RNA_property_array_dimension(&self->ptr, self->prop, nullptr) > 1) {
return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
if (RNA_property_array_dimension(&self->ptr.value(), self->prop, nullptr) > 1) {
return RNA_property_multi_array_length(&self->ptr.value(), self->prop, self->arraydim);
}
return RNA_property_array_length(&self->ptr, self->prop);
return RNA_property_array_length(&self->ptr.value(), self->prop);
}
static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
{
PYRNA_PROP_CHECK_INT(self);
return RNA_property_collection_length(&self->ptr, self->prop);
return RNA_property_collection_length(&self->ptr.value(), self->prop);
}
/* bool functions are for speed, so we can avoid getting the length
@@ -2219,14 +2207,14 @@ static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
{
PYRNA_PROP_CHECK_INT(self);
return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
return RNA_property_array_length(&self->ptr.value(), self->prop) ? 1 : 0;
}
static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
{
PYRNA_PROP_CHECK_INT(self);
return !RNA_property_collection_is_empty(&self->ptr, self->prop);
return !RNA_property_collection_is_empty(&self->ptr.value(), self->prop);
}
/* notice getting the length of the collection is avoided unless negative
@@ -2234,7 +2222,7 @@ static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
* This is done for faster lookups. */
#define PYRNA_PROP_COLLECTION_ABS_INDEX(ret_err) \
if (keynum < 0) { \
keynum_abs += RNA_property_collection_length(&self->ptr, self->prop); \
keynum_abs += RNA_property_collection_length(&self->ptr.value(), self->prop); \
if (keynum_abs < 0) { \
PyErr_Format(PyExc_IndexError, "bpy_prop_collection[%d]: out of range.", keynum); \
return ret_err; \
@@ -2250,7 +2238,7 @@ static int pyrna_prop_collection_subscript_is_valid_or_error(const PyObject *val
if (value != Py_None) {
BLI_assert(BPy_StructRNA_Check(value));
const BPy_StructRNA *value_pyrna = (const BPy_StructRNA *)value;
if (UNLIKELY(value_pyrna->ptr.type == nullptr)) {
if (UNLIKELY(value_pyrna->ptr->type == nullptr)) {
/* It's important to use a `TypeError` as that is what's returned when `__getitem__` is
* called on an object that doesn't support item access. */
PyErr_Format(PyExc_TypeError,
@@ -2268,7 +2256,7 @@ static void pyrna_prop_collection_string_subscript_unsupported_error(BPy_Propert
PyErr_Format(PyExc_TypeError,
"%.200s: %.200s.%.200s does not support string lookups",
error_prefix,
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_property_identifier(self->prop));
}
@@ -2294,7 +2282,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s
PYRNA_PROP_COLLECTION_ABS_INDEX(nullptr);
if (RNA_property_collection_lookup_int_has_fn(self->prop)) {
if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
if (RNA_property_collection_lookup_int(&self->ptr.value(), self->prop, keynum_abs, &newptr)) {
return pyrna_struct_CreatePyObject(&newptr);
}
}
@@ -2304,7 +2292,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s
PyObject *result = nullptr;
bool found = false;
CollectionPropertyIterator iter;
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
RNA_property_collection_begin(&self->ptr.value(), self->prop, &iter);
for (int i = 0; iter.valid; RNA_property_collection_next(&iter), i++) {
if (i == key) {
result = pyrna_struct_CreatePyObject(&iter.ptr);
@@ -2324,7 +2312,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s
}
}
const int len = RNA_property_collection_length(&self->ptr, self->prop);
const int len = RNA_property_collection_length(&self->ptr.value(), self->prop);
if (keynum_abs >= len) {
PyErr_Format(PyExc_IndexError,
"bpy_prop_collection[index]: "
@@ -2349,14 +2337,16 @@ static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self,
PyObject *value)
{
Py_ssize_t keynum_abs = keynum;
const PointerRNA *ptr = (value == Py_None) ? (&PointerRNA_NULL) : &((BPy_StructRNA *)value)->ptr;
const PointerRNA *ptr = (value == Py_None) ?
(&PointerRNA_NULL) :
&(reinterpret_cast<BPy_StructRNA *>(value))->ptr.value();
PYRNA_PROP_CHECK_INT(self);
PYRNA_PROP_COLLECTION_ABS_INDEX(-1);
if (!RNA_property_collection_assign_int(&self->ptr, self->prop, keynum_abs, ptr)) {
const int len = RNA_property_collection_length(&self->ptr, self->prop);
if (!RNA_property_collection_assign_int(&self->ptr.value(), self->prop, keynum_abs, ptr)) {
const int len = RNA_property_collection_length(&self->ptr.value(), self->prop);
if (keynum_abs >= len) {
PyErr_Format(PyExc_IndexError,
"bpy_prop_collection[index] = value: "
@@ -2403,7 +2393,7 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons
PYRNA_PROP_CHECK_OBJ(self);
if (RNA_property_collection_lookup_string_has_fn(self->prop)) {
if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) {
if (RNA_property_collection_lookup_string(&self->ptr.value(), self->prop, keyname, &newptr)) {
return pyrna_struct_CreatePyObject(&newptr);
}
}
@@ -2415,7 +2405,7 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons
PyObject *result = nullptr;
bool found = false;
CollectionPropertyIterator iter;
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
RNA_property_collection_begin(&self->ptr.value(), self->prop, &iter);
for (; iter.valid; RNA_property_collection_next(&iter)) {
PropertyRNA *nameprop = RNA_struct_name_property(iter.ptr.type);
/* The #RNA_property_collection_lookup_string_has_nameprop check should account for this.
@@ -2483,11 +2473,11 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
PyTuple_GET_SIZE(key));
return -1;
}
if (self->ptr.type != &RNA_BlendData) {
if (self->ptr->type != &RNA_BlendData) {
PyErr_Format(PyExc_KeyError,
"%s: is only valid for bpy.data collections, not %.200s",
err_prefix,
RNA_struct_identifier(self->ptr.type));
RNA_struct_identifier(self->ptr->type));
return -1;
}
if ((keyname = PyUnicode_AsUTF8(PyTuple_GET_ITEM(key, 0))) == nullptr) {
@@ -2506,7 +2496,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
lib = nullptr;
}
else if (PyUnicode_Check(keylib)) {
Main *bmain = static_cast<Main *>(self->ptr.data);
Main *bmain = static_cast<Main *>(self->ptr->data);
const char *keylib_str = PyUnicode_AsUTF8(keylib);
lib = static_cast<Library *>(
BLI_findstring(&bmain->libraries, keylib_str, offsetof(Library, filepath)));
@@ -2534,7 +2524,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
/* lib is either a valid pointer or nullptr,
* either way can do direct comparison with id.lib */
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
RNA_PROP_BEGIN (&self->ptr.value(), itemptr, self->prop) {
ID *id = static_cast<ID *>(itemptr.data); /* Always an ID. */
if (id->lib == lib && STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2)) {
found = true;
@@ -2587,7 +2577,7 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self,
list = PyList_New(0);
/* Skip to start. */
RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter);
RNA_property_collection_begin(&self->ptr.value(), self->prop, &rna_macro_iter);
RNA_property_collection_skip(&rna_macro_iter, start);
/* Add items until stop. */
@@ -2749,7 +2739,8 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
if (start < 0 || stop < 0) {
/* Only get the length for negative values. */
const Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
const Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr.value(),
self->prop);
if (start < 0) {
start += len;
CLAMP_MIN(start, 0);
@@ -2802,8 +2793,8 @@ static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *val
Py_TYPE(value)->tp_name);
return -1;
}
if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) {
StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type;
if ((prop_srna = RNA_property_pointer_type(&self->ptr.value(), self->prop))) {
StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr->type;
if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
PyErr_Format(PyExc_TypeError,
"bpy_prop_collection[key] = value: invalid, "
@@ -2881,7 +2872,7 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self,
if (start < 0 || stop < 0) {
/* Only get the length for negative values. */
Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr.value(), self->prop);
if (start < 0) {
start += len;
CLAMP_MIN(start, 0);
@@ -2941,7 +2932,7 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject
/* NOTE: no significant advantage with optimizing [:] slice as with collections,
* but include here for consistency with collection slice func */
const Py_ssize_t len = pyrna_prop_array_length(self);
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
return pyrna_prop_array_subscript_slice(self, &self->ptr.value(), self->prop, 0, len, len);
}
const int len = pyrna_prop_array_length(self);
@@ -2955,7 +2946,8 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject
return PyTuple_New(0);
}
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
return pyrna_prop_array_subscript_slice(
self, &self->ptr.value(), self->prop, start, stop, len);
}
PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
@@ -3261,11 +3253,11 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self,
PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self);
if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
if (!RNA_property_editable_flag(&self->ptr.value(), self->prop)) {
PyErr_Format(PyExc_AttributeError,
"bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only",
RNA_property_identifier(self->prop),
RNA_struct_identifier(self->ptr.type));
RNA_struct_identifier(self->ptr->type));
ret = -1;
}
@@ -3289,8 +3281,14 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self,
ret = 0; /* Do nothing. */
}
else if (step == 1) {
ret = prop_subscript_ass_array_slice(
&self->ptr, self->prop, self->arraydim, self->arrayoffset, start, stop, len, value);
ret = prop_subscript_ass_array_slice(&self->ptr.value(),
self->prop,
self->arraydim,
self->arrayoffset,
start,
stop,
len,
value);
}
else {
PyErr_SetString(PyExc_TypeError, "slice steps not supported with RNA");
@@ -3304,7 +3302,7 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self,
if (ret != -1) {
if (RNA_property_update_check(self->prop)) {
RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
RNA_property_update(BPY_context_get(), &self->ptr.value(), self->prop);
}
}
@@ -3378,7 +3376,7 @@ static PyNumberMethods pyrna_prop_collection_as_number = {
static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
{
return pyrna_array_contains_py(&self->ptr, self->prop, value);
return pyrna_array_contains_py(&self->ptr.value(), self->prop, value);
}
static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
@@ -3400,7 +3398,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
return -1;
}
if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) {
if (RNA_property_collection_lookup_string(&self->ptr.value(), self->prop, keyname, &newptr)) {
return 1;
}
if (pyrna_prop_collection_string_subscript_supported_or_error(
@@ -3423,12 +3421,12 @@ static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
return -1;
}
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
if (RNA_struct_idprops_check(self->ptr->type) == 0) {
PyErr_SetString(PyExc_TypeError, "bpy_struct: this type doesn't support IDProperties");
return -1;
}
IDProperty *group = RNA_struct_idprops(&self->ptr, false);
IDProperty *group = RNA_struct_idprops(&self->ptr.value(), false);
if (!group) {
return 0;
@@ -3487,7 +3485,7 @@ static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
PYRNA_STRUCT_CHECK_OBJ(self);
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
if (RNA_struct_idprops_check(self->ptr->type) == 0) {
PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
return nullptr;
}
@@ -3498,7 +3496,7 @@ static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
return nullptr;
}
IDProperty *group = RNA_struct_idprops(&self->ptr, false);
IDProperty *group = RNA_struct_idprops(&self->ptr.value(), false);
if (group == nullptr) {
PyErr_Format(PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
@@ -3512,17 +3510,17 @@ static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key)
return nullptr;
}
return BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group);
return BPy_IDGroup_WrapData(self->ptr->owner_id, idprop, group);
}
static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value)
{
PYRNA_STRUCT_CHECK_INT(self);
IDProperty *group = RNA_struct_idprops(&self->ptr, true);
IDProperty *group = RNA_struct_idprops(&self->ptr.value(), true);
#ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) {
if (rna_disallow_writes && rna_id_write_error(&self->ptr.value(), key)) {
return -1;
}
#endif /* USE_PEDANTIC_WRITE */
@@ -3535,9 +3533,9 @@ static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObje
if (value && BPy_StructRNA_Check(value)) {
BPy_StructRNA *val = (BPy_StructRNA *)value;
if (val && self->ptr.type && val->ptr.type) {
if (!RNA_struct_idprops_datablock_allowed(self->ptr.type) &&
RNA_struct_idprops_contains_datablock(val->ptr.type))
if (val && self->ptr->type && val->ptr->type) {
if (!RNA_struct_idprops_datablock_allowed(self->ptr->type) &&
RNA_struct_idprops_contains_datablock(val->ptr->type))
{
PyErr_SetString(
PyExc_TypeError,
@@ -3571,14 +3569,14 @@ static PyObject *pyrna_struct_keys(BPy_StructRNA *self)
{
PYRNA_STRUCT_CHECK_OBJ(self);
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
if (RNA_struct_idprops_check(self->ptr->type) == 0) {
PyErr_SetString(PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
return nullptr;
}
/* `group` may be nullptr. */
IDProperty *group = RNA_struct_idprops(&self->ptr, false);
return BPy_Wrap_GetKeys_View_WithID(self->ptr.owner_id, group);
IDProperty *group = RNA_struct_idprops(&self->ptr.value(), false);
return BPy_Wrap_GetKeys_View_WithID(self->ptr->owner_id, group);
}
PyDoc_STRVAR(
@@ -3596,14 +3594,14 @@ static PyObject *pyrna_struct_items(BPy_StructRNA *self)
{
PYRNA_STRUCT_CHECK_OBJ(self);
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
if (RNA_struct_idprops_check(self->ptr->type) == 0) {
PyErr_SetString(PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
return nullptr;
}
/* `group` may be nullptr. */
IDProperty *group = RNA_struct_idprops(&self->ptr, false);
return BPy_Wrap_GetItems_View_WithID(self->ptr.owner_id, group);
IDProperty *group = RNA_struct_idprops(&self->ptr.value(), false);
return BPy_Wrap_GetItems_View_WithID(self->ptr->owner_id, group);
}
PyDoc_STRVAR(
@@ -3621,15 +3619,15 @@ static PyObject *pyrna_struct_values(BPy_StructRNA *self)
{
PYRNA_STRUCT_CHECK_OBJ(self);
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
if (RNA_struct_idprops_check(self->ptr->type) == 0) {
PyErr_SetString(PyExc_TypeError,
"bpy_struct.values(): this type doesn't support IDProperties");
return nullptr;
}
/* `group` may be nullptr. */
IDProperty *group = RNA_struct_idprops(&self->ptr, false);
return BPy_Wrap_GetValues_View_WithID(self->ptr.owner_id, group);
IDProperty *group = RNA_struct_idprops(&self->ptr.value(), false);
return BPy_Wrap_GetValues_View_WithID(self->ptr->owner_id, group);
}
PyDoc_STRVAR(
@@ -3670,15 +3668,15 @@ static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *arg
return nullptr;
}
if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
if ((prop = RNA_struct_find_property(&self->ptr.value(), name)) == nullptr) {
PyErr_Format(PyExc_TypeError,
"%.200s.is_property_set(\"%.200s\") not found",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
name);
return nullptr;
}
return PyBool_FromLong(RNA_property_is_set_ex(&self->ptr, prop, use_ghost));
return PyBool_FromLong(RNA_property_is_set_ex(&self->ptr.value(), prop, use_ghost));
}
PyDoc_STRVAR(
@@ -3698,15 +3696,15 @@ static PyObject *pyrna_struct_property_unset(BPy_StructRNA *self, PyObject *args
return nullptr;
}
if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
if ((prop = RNA_struct_find_property(&self->ptr.value(), name)) == nullptr) {
PyErr_Format(PyExc_TypeError,
"%.200s.property_unset(\"%.200s\") not found",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
name);
return nullptr;
}
RNA_property_unset(&self->ptr, prop);
RNA_property_unset(&self->ptr.value(), prop);
Py_RETURN_NONE;
}
@@ -3731,10 +3729,10 @@ static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *
return nullptr;
}
if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
if ((prop = RNA_struct_find_property(&self->ptr.value(), name)) == nullptr) {
PyErr_Format(PyExc_TypeError,
"%.200s.is_property_hidden(\"%.200s\") not found",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
name);
return nullptr;
}
@@ -3762,15 +3760,15 @@ static PyObject *pyrna_struct_is_property_readonly(BPy_StructRNA *self, PyObject
return nullptr;
}
if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
if ((prop = RNA_struct_find_property(&self->ptr.value(), name)) == nullptr) {
PyErr_Format(PyExc_TypeError,
"%.200s.is_property_readonly(\"%.200s\") not found",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
name);
return nullptr;
}
return PyBool_FromLong(!RNA_property_editable(&self->ptr, prop));
return PyBool_FromLong(!RNA_property_editable(&self->ptr.value(), prop));
}
PyDoc_STRVAR(
@@ -3793,15 +3791,15 @@ static PyObject *pyrna_struct_is_property_overridable_library(BPy_StructRNA *sel
return nullptr;
}
if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
if ((prop = RNA_struct_find_property(&self->ptr.value(), name)) == nullptr) {
PyErr_Format(PyExc_TypeError,
"%.200s.is_property_overridable_library(\"%.200s\") not found",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
name);
return nullptr;
}
return PyBool_FromLong(long(RNA_property_overridable_get(&self->ptr, prop)));
return PyBool_FromLong(long(RNA_property_overridable_get(&self->ptr.value(), prop)));
}
PyDoc_STRVAR(
@@ -3825,16 +3823,16 @@ static PyObject *pyrna_struct_property_overridable_library_set(BPy_StructRNA *se
return nullptr;
}
if ((prop = RNA_struct_find_property(&self->ptr, name)) == nullptr) {
if ((prop = RNA_struct_find_property(&self->ptr.value(), name)) == nullptr) {
PyErr_Format(PyExc_TypeError,
"%.200s.property_overridable_library_set(\"%.200s\") not found",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
name);
return nullptr;
}
return PyBool_FromLong(
long(RNA_property_overridable_library_set(&self->ptr, prop, bool(is_overridable))));
long(RNA_property_overridable_library_set(&self->ptr.value(), prop, bool(is_overridable))));
}
PyDoc_STRVAR(
@@ -3863,13 +3861,13 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
return nullptr;
}
if (RNA_path_resolve_full_maybe_null(&self->ptr, path, &r_ptr, &r_prop, &index)) {
if (RNA_path_resolve_full_maybe_null(&self->ptr.value(), path, &r_ptr, &r_prop, &index)) {
if (r_prop) {
if (index != -1) {
if (index >= RNA_property_array_length(&r_ptr, r_prop) || index < 0) {
PyErr_Format(PyExc_IndexError,
"%.200s.path_resolve(\"%.200s\") index out of range",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
path);
return nullptr;
}
@@ -3889,7 +3887,7 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
PyErr_Format(PyExc_ValueError,
"%.200s.path_resolve(\"%.200s\") could not be resolved",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
path);
return nullptr;
}
@@ -3921,32 +3919,32 @@ static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
std::optional<std::string> path;
if (name) {
prop = RNA_struct_find_property(&self->ptr, name);
prop = RNA_struct_find_property(&self->ptr.value(), name);
if (prop == nullptr) {
PyErr_Format(PyExc_AttributeError,
"%.200s.path_from_id(\"%.200s\") not found",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
name);
return nullptr;
}
path = RNA_path_from_ID_to_property(&self->ptr, prop);
path = RNA_path_from_ID_to_property(&self->ptr.value(), prop);
}
else {
path = RNA_path_from_ID_to_struct(&self->ptr);
path = RNA_path_from_ID_to_struct(&self->ptr.value());
}
if (!path) {
if (name) {
PyErr_Format(PyExc_ValueError,
"%.200s.path_from_id(\"%s\") found, but does not support path creation",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
name);
}
else {
PyErr_Format(PyExc_ValueError,
"%.200s.path_from_id() does not support path creation for this type",
RNA_struct_identifier(self->ptr.type));
RNA_struct_identifier(self->ptr->type));
}
return nullptr;
}
@@ -3970,12 +3968,13 @@ static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
PropertyRNA *prop = self->prop;
PyObject *ret;
const std::optional<std::string> path = RNA_path_from_ID_to_property(&self->ptr, self->prop);
const std::optional<std::string> path = RNA_path_from_ID_to_property(&self->ptr.value(),
self->prop);
if (!path) {
PyErr_Format(PyExc_ValueError,
"%.200s.%.200s.path_from_id() does not support path creation for this type",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_property_identifier(prop));
return nullptr;
}
@@ -4000,7 +3999,7 @@ static PyObject *pyrna_prop_as_bytes(BPy_PropertyRNA *self)
if (RNA_property_type(self->prop) != PROP_STRING) {
PyErr_Format(PyExc_TypeError,
"%.200s.%.200s.as_bytes() must be a string",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_property_identifier(self->prop));
return nullptr;
}
@@ -4010,7 +4009,7 @@ static PyObject *pyrna_prop_as_bytes(BPy_PropertyRNA *self)
int buf_len;
buf = RNA_property_string_get_alloc(
&self->ptr, self->prop, buf_fixed, sizeof(buf_fixed), &buf_len);
&self->ptr.value(), self->prop, buf_fixed, sizeof(buf_fixed), &buf_len);
ret = PyBytes_FromStringAndSize(buf, buf_len);
@@ -4033,7 +4032,7 @@ PyDoc_STRVAR(
" however in rare cases it's useful to call explicitly.\n");
static PyObject *pyrna_prop_update(BPy_PropertyRNA *self)
{
RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
RNA_property_update(BPY_context_get(), &self->ptr.value(), self->prop);
Py_RETURN_NONE;
}
@@ -4052,7 +4051,7 @@ static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
PYRNA_STRUCT_CHECK_OBJ(self);
PointerRNA r_ptr = RNA_pointer_recast(&self->ptr);
PointerRNA r_ptr = RNA_pointer_recast(&self->ptr.value());
return pyrna_struct_CreatePyObject(&r_ptr);
}
@@ -4077,7 +4076,7 @@ static PyObject *pyrna_struct_bl_rna_find_subclass_recursive(PyObject *cls, cons
BPy_StructRNA *py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)subcls)->tp_dict,
bpy_intern_str_bl_rna);
if (py_srna) {
StructRNA *srna = static_cast<StructRNA *>(py_srna->ptr.data);
StructRNA *srna = static_cast<StructRNA *>(py_srna->ptr->data);
if (STREQ(id, RNA_struct_identifier(srna))) {
ret_test = subcls;
break;
@@ -4141,7 +4140,7 @@ static PyObject *pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args)
PyErr_SetString(PyExc_ValueError, "Not a registered class");
return nullptr;
}
const StructRNA *srna_base = static_cast<const StructRNA *>(py_srna->ptr.data);
const StructRNA *srna_base = static_cast<const StructRNA *>(py_srna->ptr->data);
if (srna_base == &RNA_Node) {
/* If the given idname is an alias, translate it to the proper idname. */
@@ -4194,7 +4193,7 @@ static void pyrna_dir_members_py(PyObject *list, PyObject *self)
if (RNA_property_type(self_prop->prop) == PROP_COLLECTION) {
PointerRNA r_ptr;
if (RNA_property_collection_type_get(&self_prop->ptr, self_prop->prop, &r_ptr)) {
if (RNA_property_collection_type_get(&self_prop->ptr.value(), self_prop->prop, &r_ptr)) {
PyObject *cls = pyrna_struct_Subtype(&r_ptr); /* borrows */
dict = ((PyTypeObject *)cls)->tp_dict;
pyrna_dir_members_py__add_keys(list, dict);
@@ -4267,10 +4266,10 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
pyrna_dir_members_py(ret, (PyObject *)self);
}
pyrna_dir_members_rna(ret, &self->ptr);
pyrna_dir_members_rna(ret, &self->ptr.value());
if (self->ptr.type == &RNA_Context) {
ListBase lb = CTX_data_dir_get(static_cast<const bContext *>(self->ptr.data));
if (self->ptr->type == &RNA_Context) {
ListBase lb = CTX_data_dir_get(static_cast<const bContext *>(self->ptr->data));
LISTBASE_FOREACH (LinkData *, link, &lb) {
PyList_APPEND(ret, PyUnicode_FromString(static_cast<const char *>(link->data)));
@@ -4304,12 +4303,12 @@ static PyObject *pyrna_struct_id_properties_ensure(BPy_StructRNA *self)
{
PYRNA_STRUCT_CHECK_OBJ(self);
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
if (RNA_struct_idprops_check(self->ptr->type) == 0) {
PyErr_SetString(PyExc_TypeError, "This type doesn't support IDProperties");
return nullptr;
}
IDProperty *idprops = RNA_struct_idprops(&self->ptr, true);
IDProperty *idprops = RNA_struct_idprops(&self->ptr.value(), true);
/* This is a paranoid check that theoretically might not be necessary.
* It allows the possibility that some structs can't ensure IDProperties. */
@@ -4318,7 +4317,7 @@ static PyObject *pyrna_struct_id_properties_ensure(BPy_StructRNA *self)
}
BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &BPy_IDGroup_Type);
group->owner_id = self->ptr.owner_id;
group->owner_id = self->ptr->owner_id;
group->prop = idprops;
group->parent = nullptr;
return (PyObject *)group;
@@ -4336,7 +4335,7 @@ static PyObject *pyrna_struct_id_properties_ui(BPy_StructRNA *self, PyObject *ar
{
PYRNA_STRUCT_CHECK_OBJ(self);
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
if (RNA_struct_idprops_check(self->ptr->type) == 0) {
PyErr_SetString(PyExc_TypeError, "This type doesn't support IDProperties");
return nullptr;
}
@@ -4346,7 +4345,7 @@ static PyObject *pyrna_struct_id_properties_ui(BPy_StructRNA *self, PyObject *ar
return nullptr;
}
IDProperty *parent_group = RNA_struct_idprops(&self->ptr, true);
IDProperty *parent_group = RNA_struct_idprops(&self->ptr.value(), true);
/* This is a paranoid check that theoretically might not be necessary.
* It allows the possibility that some structs can't ensure IDProperties. */
@@ -4381,12 +4380,12 @@ static PyObject *pyrna_struct_id_properties_clear(BPy_StructRNA *self)
{
PYRNA_STRUCT_CHECK_OBJ(self);
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
if (RNA_struct_idprops_check(self->ptr->type) == 0) {
PyErr_SetString(PyExc_TypeError, "This type doesn't support IDProperties");
return nullptr;
}
IDProperty **idprops = RNA_struct_idprops_p(&self->ptr);
IDProperty **idprops = RNA_struct_idprops_p(&self->ptr.value());
if (*idprops) {
IDP_FreeProperty(*idprops);
@@ -4416,7 +4415,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
name[0] == '_')
{
/* Annoying exception, maybe we need to have different types for this... */
if (STR_ELEM(name, "__getitem__", "__setitem__") && !RNA_struct_idprops_check(self->ptr.type))
if (STR_ELEM(name, "__getitem__", "__setitem__") && !RNA_struct_idprops_check(self->ptr->type))
{
PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
ret = nullptr;
@@ -4425,15 +4424,16 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
}
}
else if ((prop = RNA_struct_find_property(&self->ptr, name))) {
ret = pyrna_prop_to_py(&self->ptr, prop);
else if ((prop = RNA_struct_find_property(&self->ptr.value(), name))) {
ret = pyrna_prop_to_py(&self->ptr.value(), prop);
}
/* RNA function only if callback is declared (no optional functions). */
else if ((func = RNA_struct_find_function(self->ptr.type, name)) && RNA_function_defined(func)) {
ret = pyrna_func_to_py(&self->ptr, func);
else if ((func = RNA_struct_find_function(self->ptr->type, name)) && RNA_function_defined(func))
{
ret = pyrna_func_to_py(&self->ptr.value(), func);
}
else if (self->ptr.type == &RNA_Context) {
bContext *C = static_cast<bContext *>(self->ptr.data);
else if (self->ptr->type == &RNA_Context) {
bContext *C = static_cast<bContext *>(self->ptr->data);
if (C == nullptr) {
PyErr_Format(PyExc_AttributeError,
"bpy_struct: Context is 'nullptr', can't get \"%.200s\" from context",
@@ -4687,7 +4687,7 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject
PYRNA_STRUCT_CHECK_INT(self);
#ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
if (rna_disallow_writes && rna_id_write_error(&self->ptr.value(), pyname)) {
return -1;
}
#endif /* USE_PEDANTIC_WRITE */
@@ -4696,19 +4696,19 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject
PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string");
return -1;
}
if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr, name))) {
if (!RNA_property_editable_flag(&self->ptr, prop)) {
if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr.value(), name))) {
if (!RNA_property_editable_flag(&self->ptr.value(), prop)) {
PyErr_Format(PyExc_AttributeError,
"bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only",
RNA_property_identifier(prop),
RNA_struct_identifier(self->ptr.type));
RNA_struct_identifier(self->ptr->type));
return -1;
}
}
else if (self->ptr.type == &RNA_Context) {
else if (self->ptr->type == &RNA_Context) {
/* Code just raises correct error, context prop's can't be set,
* unless it's a part of the py class. */
bContext *C = static_cast<bContext *>(self->ptr.data);
bContext *C = static_cast<bContext *>(self->ptr->data);
if (C == nullptr) {
PyErr_Format(PyExc_AttributeError,
"bpy_struct: Context is 'nullptr', can't set \"%.200s\" from context",
@@ -4739,7 +4739,8 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject
PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported");
return -1;
}
return pyrna_py_to_prop(&self->ptr, prop, nullptr, value, "bpy_struct: item.attr = val:");
return pyrna_py_to_prop(
&self->ptr.value(), prop, nullptr, value, "bpy_struct: item.attr = val:");
}
return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
@@ -4759,7 +4760,7 @@ static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
}
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
if (RNA_property_collection_type_get(&self->ptr.value(), self->prop, &r_ptr)) {
pyrna_dir_members_rna(ret, &r_ptr);
}
}
@@ -4786,7 +4787,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject
FunctionRNA *func;
PointerRNA r_ptr;
if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
if (RNA_property_collection_type_get(&self->ptr.value(), self->prop, &r_ptr)) {
if ((prop = RNA_struct_find_property(&r_ptr, name))) {
ret = pyrna_prop_to_py(&r_ptr, prop);
@@ -4794,7 +4795,8 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject
}
if ((func = RNA_struct_find_function(r_ptr.type, name))) {
PyObject *self_collection = pyrna_struct_CreatePyObject(&r_ptr);
ret = pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func);
ret = pyrna_func_to_py(
&(reinterpret_cast<BPy_DummyPointerRNA *>(self_collection))->ptr.value(), func);
Py_DECREF(self_collection);
return ret;
@@ -4816,7 +4818,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject
if ((ret == nullptr) && (name[0] != '_')) {
/* Since this is least common case, handle it last. */
PointerRNA r_ptr;
if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
if (RNA_property_collection_type_get(&self->ptr.value(), self->prop, &r_ptr)) {
PyObject *cls = pyrna_struct_Subtype(&r_ptr);
ret = _PyObject_GenericGetAttrWithDict(cls, pyname, nullptr, 1);
Py_DECREF(cls);
@@ -4855,7 +4857,7 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam
PointerRNA r_ptr;
#ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) {
if (rna_disallow_writes && rna_id_write_error(&self->ptr.value(), pyname)) {
return -1;
}
#endif /* USE_PEDANTIC_WRITE */
@@ -4868,7 +4870,7 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam
PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported");
return -1;
}
if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
if (RNA_property_collection_type_get(&self->ptr.value(), self->prop, &r_ptr)) {
if ((prop = RNA_struct_find_property(&r_ptr, name))) {
/* pyrna_py_to_prop sets its own exceptions. */
return pyrna_py_to_prop(
@@ -4888,12 +4890,12 @@ static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self)
PointerRNA r_ptr;
#ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
if (rna_disallow_writes && rna_id_write_error(&self->ptr.value(), nullptr)) {
return nullptr;
}
#endif /* USE_PEDANTIC_WRITE */
RNA_property_collection_add(&self->ptr, self->prop, &r_ptr);
RNA_property_collection_add(&self->ptr.value(), self->prop, &r_ptr);
if (!r_ptr.data) {
PyErr_SetString(PyExc_TypeError,
"bpy_prop_collection.add(): not supported for this collection");
@@ -4908,7 +4910,7 @@ static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyOb
const int key = PyLong_AsLong(value);
#ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
if (rna_disallow_writes && rna_id_write_error(&self->ptr.value(), nullptr)) {
return nullptr;
}
#endif /* USE_PEDANTIC_WRITE */
@@ -4918,7 +4920,7 @@ static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyOb
return nullptr;
}
if (!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
if (!RNA_property_collection_remove(&self->ptr.value(), self->prop, key)) {
PyErr_SetString(PyExc_TypeError,
"bpy_prop_collection.remove() not supported for this collection");
return nullptr;
@@ -4930,12 +4932,12 @@ static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyOb
static PyObject *pyrna_prop_collection_idprop_clear(BPy_PropertyRNA *self)
{
#ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
if (rna_disallow_writes && rna_id_write_error(&self->ptr.value(), nullptr)) {
return nullptr;
}
#endif /* USE_PEDANTIC_WRITE */
RNA_property_collection_clear(&self->ptr, self->prop);
RNA_property_collection_clear(&self->ptr.value(), self->prop);
Py_RETURN_NONE;
}
@@ -4945,7 +4947,7 @@ static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObje
int key = 0, pos = 0;
#ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, nullptr)) {
if (rna_disallow_writes && rna_id_write_error(&self->ptr.value(), nullptr)) {
return nullptr;
}
#endif /* USE_PEDANTIC_WRITE */
@@ -4955,7 +4957,7 @@ static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObje
return nullptr;
}
if (!RNA_property_collection_move(&self->ptr, self->prop, key, pos)) {
if (!RNA_property_collection_move(&self->ptr.value(), self->prop, key, pos)) {
PyErr_SetString(PyExc_TypeError,
"bpy_prop_collection.move() not supported for this collection");
return nullptr;
@@ -4972,8 +4974,8 @@ PyDoc_STRVAR(
static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self, void * /*closure*/)
{
/* Used for struct and pointer since both have a ptr. */
if (self->ptr.owner_id) {
PointerRNA id_ptr = RNA_id_pointer_create((ID *)self->ptr.owner_id);
if (self->ptr->owner_id) {
PointerRNA id_ptr = RNA_id_pointer_create((ID *)self->ptr->owner_id);
return pyrna_struct_CreatePyObject(&id_ptr);
}
@@ -4986,7 +4988,7 @@ PyDoc_STRVAR(
"The data this property is using, *type* :class:`bpy.types.bpy_struct`");
static PyObject *pyrna_struct_get_data(BPy_DummyPointerRNA *self, void * /*closure*/)
{
return pyrna_struct_CreatePyObject(&self->ptr);
return pyrna_struct_CreatePyObject(&self->ptr.value());
}
PyDoc_STRVAR(
@@ -5050,7 +5052,7 @@ static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self)
char name[256], *name_ptr;
int name_len;
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
RNA_PROP_BEGIN (&self->ptr.value(), itemptr, self->prop) {
name_ptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &name_len);
if (name_ptr) {
@@ -5084,7 +5086,7 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
int name_len;
int i = 0;
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
RNA_PROP_BEGIN (&self->ptr.value(), itemptr, self->prop) {
if (itemptr.data) {
/* Add to Python list. */
item = PyTuple_New(2);
@@ -5155,17 +5157,17 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
}
/* Mostly copied from BPy_IDGroup_Map_GetItem. */
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
if (RNA_struct_idprops_check(self->ptr->type) == 0) {
PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
return nullptr;
}
group = RNA_struct_idprops(&self->ptr, false);
group = RNA_struct_idprops(&self->ptr.value(), false);
if (group) {
idprop = IDP_GetPropertyFromGroup(group, key);
if (idprop) {
return BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group);
return BPy_IDGroup_WrapData(self->ptr->owner_id, idprop, group);
}
}
@@ -5200,12 +5202,12 @@ static PyObject *pyrna_struct_pop(BPy_StructRNA *self, PyObject *args)
}
/* Mostly copied from BPy_IDGroup_Map_GetItem. */
if (RNA_struct_idprops_check(self->ptr.type) == 0) {
if (RNA_struct_idprops_check(self->ptr->type) == 0) {
PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
return nullptr;
}
group = RNA_struct_idprops(&self->ptr, false);
group = RNA_struct_idprops(&self->ptr.value(), false);
if (group) {
idprop = IDP_GetPropertyFromGroup(group, key);
@@ -5242,7 +5244,7 @@ PyDoc_STRVAR(
" pass blender data to their own C/Python modules.\n");
static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self)
{
return PyLong_FromVoidPtr(self->ptr.data);
return PyLong_FromVoidPtr(self->ptr->data);
}
PyDoc_STRVAR(
@@ -5274,7 +5276,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
if (PyUnicode_Check(key_ob)) {
const char *key = PyUnicode_AsUTF8(key_ob);
if (RNA_property_collection_lookup_string(&self->ptr, self->prop, key, &newptr)) {
if (RNA_property_collection_lookup_string(&self->ptr.value(), self->prop, key, &newptr)) {
return pyrna_struct_CreatePyObject(&newptr);
}
if (pyrna_prop_collection_string_subscript_supported_or_error(self,
@@ -5324,7 +5326,7 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key
PYRNA_PROP_CHECK_OBJ(self);
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
RNA_PROP_BEGIN (&self->ptr.value(), itemptr, self->prop) {
name_ptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &name_len);
if (name_ptr) {
@@ -5361,7 +5363,7 @@ static bool foreach_attr_type(BPy_PropertyRNA *self,
*r_is_empty = true;
/* NOTE: this is fail with zero length lists, so don't let this get called in that case. */
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
RNA_PROP_BEGIN (&self->ptr.value(), itemptr, self->prop) {
prop = RNA_struct_find_property(&itemptr, attr);
if (prop) {
*r_raw_type = RNA_property_raw_type(prop);
@@ -5418,10 +5420,10 @@ static int foreach_parse_args(BPy_PropertyRNA *self,
int array_tot;
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
array_tot = RNA_property_collection_length(&self->ptr, self->prop);
array_tot = RNA_property_collection_length(&self->ptr.value(), self->prop);
}
else {
array_tot = RNA_property_array_length(&self->ptr, self->prop);
array_tot = RNA_property_array_length(&self->ptr.value(), self->prop);
}
if (array_tot == 0) {
PyErr_Format(PyExc_TypeError,
@@ -5437,7 +5439,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self,
PyErr_Format(PyExc_AttributeError,
"%s(..) '%.200s.%200s[...]' elements have no attribute '%.200s'",
function_name,
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_property_identifier(self->prop),
*r_attr);
return -1;
@@ -5589,7 +5591,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
if (buffer_is_compat) {
ok = RNA_property_collection_raw_set(
nullptr, &self->ptr, self->prop, attr, buf.buf, raw_type, tot);
nullptr, &self->ptr.value(), self->prop, attr, buf.buf, raw_type, tot);
}
PyBuffer_Release(&buf);
@@ -5646,7 +5648,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
}
ok = RNA_property_collection_raw_set(
nullptr, &self->ptr, self->prop, attr, array, raw_type, tot);
nullptr, &self->ptr.value(), self->prop, attr, array, raw_type, tot);
}
}
else {
@@ -5665,7 +5667,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
if (buffer_is_compat) {
ok = RNA_property_collection_raw_get(
nullptr, &self->ptr, self->prop, attr, buf.buf, raw_type, tot);
nullptr, &self->ptr.value(), self->prop, attr, buf.buf, raw_type, tot);
}
PyBuffer_Release(&buf);
@@ -5677,7 +5679,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
array = PyMem_Malloc(size * tot);
ok = RNA_property_collection_raw_get(
nullptr, &self->ptr, self->prop, attr, array, raw_type, tot);
nullptr, &self->ptr.value(), self->prop, attr, array, raw_type, tot);
if (!ok) {
/* Skip the loop. */
@@ -5750,7 +5752,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
}
if (set) {
RNA_property_update(BPY_context_get(), &self->ptr, self->prop);
RNA_property_update(BPY_context_get(), &self->ptr.value(), self->prop);
}
Py_RETURN_NONE;
}
@@ -5812,7 +5814,7 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self,
/* NOTE: in this case it's important to use the flat-array size and *not* the result of
* `len()`, which uses #pyrna_prop_array_length, see !116457 for details. */
size = RNA_property_array_length(&self->ptr, self->prop);
size = RNA_property_array_length(&self->ptr.value(), self->prop);
seq_size = PySequence_Size(seq);
if (size != seq_size) {
@@ -5834,10 +5836,11 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self,
Py_DECREF(item);
}
RNA_property_int_set_array(&self->ptr, self->prop, static_cast<const int *>(array));
RNA_property_int_set_array(
&self->ptr.value(), self->prop, static_cast<const int *>(array));
}
else {
RNA_property_int_get_array(&self->ptr, self->prop, static_cast<int *>(array));
RNA_property_int_get_array(&self->ptr.value(), self->prop, static_cast<int *>(array));
for (i = 0; i < size; i++) {
item = PyLong_FromLong(long(((int *)array)[i]));
@@ -5856,10 +5859,12 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self,
Py_DECREF(item);
}
RNA_property_float_set_array(&self->ptr, self->prop, static_cast<const float *>(array));
RNA_property_float_set_array(
&self->ptr.value(), self->prop, static_cast<const float *>(array));
}
else {
RNA_property_float_get_array(&self->ptr, self->prop, static_cast<float *>(array));
RNA_property_float_get_array(
&self->ptr.value(), self->prop, static_cast<float *>(array));
for (i = 0; i < size; i++) {
item = PyFloat_FromDouble(double(((float *)array)[i]));
@@ -5900,19 +5905,21 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self,
switch (prop_type) {
case PROP_INT:
if (do_set) {
RNA_property_int_set_array(&self->ptr, self->prop, static_cast<const int *>(buf.buf));
RNA_property_int_set_array(
&self->ptr.value(), self->prop, static_cast<const int *>(buf.buf));
}
else {
RNA_property_int_get_array(&self->ptr, self->prop, static_cast<int *>(buf.buf));
RNA_property_int_get_array(&self->ptr.value(), self->prop, static_cast<int *>(buf.buf));
}
break;
case PROP_FLOAT:
if (do_set) {
RNA_property_float_set_array(
&self->ptr, self->prop, static_cast<const float *>(buf.buf));
&self->ptr.value(), self->prop, static_cast<const float *>(buf.buf));
}
else {
RNA_property_float_get_array(&self->ptr, self->prop, static_cast<float *>(buf.buf));
RNA_property_float_get_array(
&self->ptr.value(), self->prop, static_cast<float *>(buf.buf));
}
break;
case PROP_BOOLEAN:
@@ -5969,7 +5976,7 @@ static PyObject *pyrna_prop_array_iter(BPy_PropertyArrayRNA *self)
PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self);
len = pyrna_prop_array_length(self);
ret = pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
ret = pyrna_prop_array_subscript_slice(self, &self->ptr.value(), self->prop, 0, len, len);
/* we know this is a list so no need to PyIter_Check
* otherwise it could be nullptr (unlikely) if conversion failed */
@@ -5981,15 +5988,17 @@ static PyObject *pyrna_prop_array_iter(BPy_PropertyArrayRNA *self)
return iter;
}
static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self);
static PyObject *pyrna_prop_collection_iter(PyObject *self);
#ifndef USE_PYRNA_ITER
static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_iter(PyObject *self)
{
BPy_PropertyRNA *self_property = reinterpret_cast<BPy_PropertyRNA *>(self);
/* Try get values from a collection. */
PyObject *ret;
PyObject *iter = nullptr;
ret = pyrna_prop_collection_values(self);
ret = pyrna_prop_collection_values(self_property);
/* we know this is a list so no need to PyIter_Check
* otherwise it could be nullptr (unlikely) if conversion failed */
@@ -6174,84 +6183,6 @@ static PyMethodDef pyrna_prop_collection_idprop_methods[] = {
# pragma GCC diagnostic pop
#endif
/**
* only needed for sub-typing, so a new class gets a valid #BPy_StructRNA
* TODO: also accept useful args.
*/
static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * /*kwds*/)
{
if (PyTuple_GET_SIZE(args) == 1) {
BPy_StructRNA *base = (BPy_StructRNA *)PyTuple_GET_ITEM(args, 0);
if (Py_TYPE(base) == type) {
Py_INCREF(base);
return (PyObject *)base;
}
if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) {
/* this almost never runs, only when using user defined subclasses of built-in object.
* this isn't common since it's NOT related to registerable subclasses. eg:
*
* >>> class MyObSubclass(bpy.types.Object):
* ... def test_func(self):
* ... print(100)
* ...
* >>> myob = MyObSubclass(bpy.context.object)
* >>> myob.test_func()
* 100
*
* Keep this since it could be useful.
*/
BPy_StructRNA *ret;
if ((ret = (BPy_StructRNA *)type->tp_alloc(type, 0))) {
ret->ptr = base->ptr;
#ifdef USE_PYRNA_STRUCT_REFERENCE
/* #PyType_GenericAlloc will have set tracking.
* We only want tracking when `StructRNA.reference` has been set. */
PyObject_GC_UnTrack(ret);
#endif
}
/* Pass on exception & nullptr if tp_alloc fails. */
return (PyObject *)ret;
}
/* Error, invalid type given. */
PyErr_Format(PyExc_TypeError,
"bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct",
type->tp_name);
return nullptr;
}
PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument");
return nullptr;
}
/**
* Only needed for sub-typing, so a new class gets a valid #BPy_StructRNA
* TODO: also accept useful args.
*/
static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject * /*kwds*/)
{
BPy_PropertyRNA *base;
if (!PyArg_ParseTuple(args, "O!:bpy_prop.__new__", &pyrna_prop_Type, &base)) {
return nullptr;
}
if (type == Py_TYPE(base)) {
return Py_NewRef(base);
}
if (PyType_IsSubtype(type, &pyrna_prop_Type)) {
BPy_PropertyRNA *ret = (BPy_PropertyRNA *)type->tp_alloc(type, 0);
ret->ptr = base->ptr;
ret->prop = base->prop;
return (PyObject *)ret;
}
PyErr_Format(PyExc_TypeError,
"bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop",
type->tp_name);
return nullptr;
}
static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
{
PyObject *ret;
@@ -6380,11 +6311,18 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
}
case PROP_POINTER: {
PointerRNA newptr;
PointerRNA *newptr_p = nullptr;
StructRNA *ptype = RNA_property_pointer_type(ptr, prop);
if (flag_parameter & PARM_RNAPTR) {
/* In this case we get the full ptr. */
newptr = *(PointerRNA *)data;
if (flag & PROP_THICK_WRAP) {
/* `data` points to a PointerRNA. */
newptr_p = static_cast<PointerRNA *>(data);
}
else {
/* `data` points to a pointer to a PointerRNA. */
newptr_p = *reinterpret_cast<PointerRNA **>(data);
}
}
else {
if (RNA_struct_is_ID(ptype)) {
@@ -6397,10 +6335,11 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
* easy to debug since they are all ID's */
newptr = RNA_pointer_create(ptr->owner_id, ptype, *(void **)data);
}
newptr_p = &newptr;
}
if (newptr.data) {
ret = pyrna_struct_CreatePyObject(&newptr);
if (newptr_p->data) {
ret = pyrna_struct_CreatePyObject(newptr_p);
}
else {
ret = Py_None;
@@ -6461,7 +6400,7 @@ static void pyrna_func_error_prefix(BPy_FunctionRNA *self,
char *error,
const size_t error_size)
{
PointerRNA *self_ptr = &self->ptr;
PointerRNA *self_ptr = &self->ptr.value();
FunctionRNA *self_func = self->func;
if (parm_index == -1) {
BLI_snprintf(error,
@@ -6485,7 +6424,7 @@ static void pyrna_func_error_prefix(BPy_FunctionRNA *self,
static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw)
{
/* NOTE: both BPy_StructRNA and BPy_PropertyRNA can be used here. */
PointerRNA *self_ptr = &self->ptr;
PointerRNA *self_ptr = &self->ptr.value();
FunctionRNA *self_func = self->func;
ParameterList parms;
@@ -6805,7 +6744,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void * /*closure*/)
std::string args = RNA_function_as_string_keywords(nullptr, self->func, true, true, INT_MAX);
ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s",
RNA_struct_identifier(self->ptr.type),
RNA_struct_identifier(self->ptr->type),
RNA_function_identifier(self->func),
args.c_str(),
RNA_function_ui_description(self->func));
@@ -6873,13 +6812,44 @@ PyTypeObject pyrna_struct_meta_idprop_Type = {
/*-----------------------BPy_StructRNA method def------------------------------*/
/**
* \defgroup BPY RNA Struct Type
*
* These BPy_StructRNA objects should be created the standard way (calling their type objects
* using #PyObject_CallOneArg or similar). One and only one arg is expected currently.
*
* This special handling allows to construct an object from a python-defined derived type of
* `bpy_struct`, using an existing base struct object as source of data.
*
* It also allows internal bpy_rna.cc code to pass the private #BPy_RNANoInit_object token to
* create property objects without initializing them, which avoids double-initialization from
* functions like #pyrna_struct_CreatePyObject etc.
*
* \note: Subclassingfrom python isn't common since it's NOT related to registerable subclasses.
* eg:
*
* >>> class MyObSubclass(bpy.types.Object):
* ... def test_func(self):
* ... print(100)
* ...
* >>> myob = MyObSubclass(bpy.context.object)
* >>> myob.test_func()
* 100
*
* @{
*/
static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * /*kwds*/);
static int pyrna_struct_init(PyObject *self, PyObject *args, PyObject * /*kwds*/);
static void pyrna_struct_dealloc(PyObject *self);
PyTypeObject pyrna_struct_Type = {
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
/*tp_name*/ "bpy_struct",
/*tp_basicsize*/ sizeof(BPy_StructRNA),
/*tp_itemsize*/ 0,
/*tp_dealloc*/ (destructor)pyrna_struct_dealloc,
/*tp_vectorcall_offset*/ 0,
/*tp_dealloc*/ pyrna_struct_dealloc,
/*tp_vectorcall_offset */ 0,
/*tp_getattr*/ nullptr,
/*tp_setattr*/ nullptr,
/*tp_as_async*/ nullptr,
@@ -6922,7 +6892,7 @@ PyTypeObject pyrna_struct_Type = {
/*tp_descr_get*/ nullptr,
/*tp_descr_set*/ nullptr,
/*tp_dictoffset*/ 0,
/*tp_init*/ nullptr,
/*tp_init*/ pyrna_struct_init,
/*tp_alloc*/ nullptr,
/*tp_new*/ pyrna_struct_new,
/*tp_free*/ nullptr,
@@ -6938,14 +6908,187 @@ PyTypeObject pyrna_struct_Type = {
/*tp_vectorcall*/ nullptr,
};
static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * /*kwds*/)
{
if (PyTuple_GET_SIZE(args) != 1) {
PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(struct): expected a single argument");
return nullptr;
}
PyObject *arg_1 = PyTuple_GET_ITEM(args, 0);
/* Ignore the special 'PyCapsule' argument used only by internal bpy_rna code. */
if (!PyCapsule_CheckExact(arg_1)) {
BPy_StructRNA *base = reinterpret_cast<BPy_StructRNA *>(arg_1);
/* Error, invalid type given. */
if (!PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) {
PyErr_Format(
PyExc_TypeError,
"bpy_struct.__new__(struct): struct type '%.200s' is not a subtype of bpy_struct",
Py_TYPE(base)->tp_name);
return nullptr;
}
/* Same type, simply use the given data. */
if (Py_TYPE(base) == type) {
BLI_assert(base->ptr.has_value());
Py_INCREF(base);
return reinterpret_cast<PyObject *>(base);
}
/* NOTE: Further copy of the 'base' content into the new object will happen in
* #pyrna_struct_init. */
}
/* Only allocate the pyobject data, do not construct/initialize anything else. */
PyObject *self = type->tp_alloc(type, 0);
BPy_StructRNA *self_struct = reinterpret_cast<BPy_StructRNA *>(self);
if (self) {
#ifdef USE_PYRNA_STRUCT_REFERENCE
/* #PyType_GenericAlloc will have set tracking.
* We only want tracking when `StructRNA.reference` has been set. */
PyObject_GC_UnTrack(self);
#endif
self_struct->ptr = std::nullopt;
}
/* Pass on exception & nullptr if tp_alloc fails. */
return self;
}
static int pyrna_struct_init(PyObject *self, PyObject *args, PyObject * /*kwds*/)
{
BPy_StructRNA *self_struct = reinterpret_cast<BPy_StructRNA *>(self);
size_t args_num = PyTuple_GET_SIZE(args);
if (args_num != 1) {
PyErr_Format(PyExc_TypeError, "bpy_struct.__init__(self, struct): expected a single argument");
return -1;
}
PyObject *arg_1 = PyTuple_GET_ITEM(args, 0);
const PointerRNA *ptr = nullptr;
if (PyCapsule_CheckExact(arg_1)) {
/* `bpy_rna` internal code will call object creation with a PyCapsule argument wrapping up a
* PointerRNA pointer. */
ptr = static_cast<PointerRNA *>(
PyCapsule_GetPointer(arg_1, BPy_capsule_PointerRNA_identifier));
}
else {
BPy_StructRNA *base_struct = reinterpret_cast<BPy_StructRNA *>(arg_1);
/* Error, invalid type given. */
if (!PyType_IsSubtype(Py_TYPE(base_struct), &pyrna_struct_Type)) {
PyErr_Format(PyExc_TypeError,
"bpy_struct.__init__(self, struct): struct type '%.200s' is not a subtype of "
"bpy_struct",
Py_TYPE(base_struct)->tp_name);
return -1;
}
/* Same object as the 'base' argument (see #pyrna_struct_new), nothing to do . */
if (base_struct == self_struct) {
BLI_assert(self_struct->ptr.has_value());
return 0;
}
/* Else, use data from the base to initialize this object. */
ptr = &base_struct->ptr.value();
}
if (ptr == nullptr) {
PyErr_Format(PyExc_TypeError,
"bpy_struct.__init__(self, struct): failed to get a valid PointerRNA data "
"from the given `struct` argument");
return -1;
}
self_struct->ptr.reset();
self_struct->ptr = *ptr;
return 0;
}
/* Own dealloc so that the PointerRNA can be destructed, and the IDProperty storage can be freed if
* needed.
*
* Note: This should rather be in `tp_finalize` (aka `__del__`), but static types default dealloc
* never calls this. */
static void pyrna_struct_dealloc(PyObject *self)
{
/* Save the current exception, if any. */
PyObject *error_type, *error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
BPy_StructRNA *self_struct = reinterpret_cast<BPy_StructRNA *>(self);
#ifdef PYRNA_FREE_SUPPORT
if (self_struct->freeptr && self_struct->ptr->data) {
IDP_FreeProperty(self_struct->ptr->data);
self_struct->ptr->data = nullptr;
}
#endif /* PYRNA_FREE_SUPPORT */
#ifdef USE_WEAKREFS
if (self_struct->in_weakreflist != nullptr) {
PyObject_ClearWeakRefs(self);
}
#endif
#ifdef USE_PYRNA_STRUCT_REFERENCE
if (self_struct->reference) {
PyObject_GC_UnTrack(self);
pyrna_struct_clear(self_struct);
}
else {
PyTypeObject *base = Py_TYPE(self)->tp_base;
/* Python temporarily tracks these types when freeing, see Python bug 26617. */
if (base && PyType_IS_GC(base)) {
PyObject_GC_UnTrack(self);
}
BLI_assert(!PyObject_GC_IsTracked(self));
}
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
self_struct->ptr.~optional();
Py_TYPE(self)->tp_free(self);
/* Restore the saved exception. */
PyErr_Restore(error_type, error_value, error_traceback);
}
/** @} */
/*-----------------------BPy_PropertyRNA method def------------------------------*/
/**
* \defgroup BPY RNA Property Types
*
* These BPy_PropertyRNA objects should be created the standard way (calling their type objects
* using #PyObject_CallOneArg or similar). One and only one arg is expected currently.
*
* This special handling allows to construct an object from a python-defined derived type of
* `bpy_property`, using an existing base property object as source of data.
*
* It also allows internal bpy_rna.cc code to pass the private #BPy_RNANoInit_object token to
* create property objects without initializing them, which avoids double-initialization from
* functions like #pyrna_prop_CreatePyObject etc.
*
* \note: This isn't common since it's NOT related to registerable subclasses. eg:
*
* TODO Add python code example of using this overriding feature.
*
* @{
*/
static PyObject *pyrna_property_new(PyTypeObject *type, PyObject *args, PyObject * /*kwds*/);
static int pyrna_property_init(PyObject *self, PyObject *args, PyObject * /*kwds*/);
static void pyrna_property_dealloc(PyObject *self);
static int pyrna_property_array_init(PyObject *self, PyObject *args, PyObject * /*kwds*/);
PyTypeObject pyrna_prop_Type = {
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
/*tp_name*/ "bpy_prop",
/*tp_basicsize*/ sizeof(BPy_PropertyRNA),
/*tp_itemsize*/ 0,
/*tp_dealloc*/ (destructor)pyrna_prop_dealloc,
/*tp_dealloc*/ pyrna_property_dealloc,
/*tp_vectorcall_offset*/ 0,
/*tp_getattr*/ nullptr,
/*tp_setattr*/ nullptr,
@@ -6980,9 +7123,9 @@ PyTypeObject pyrna_prop_Type = {
/*tp_descr_get*/ nullptr,
/*tp_descr_set*/ nullptr,
/*tp_dictoffset*/ 0,
/*tp_init*/ nullptr,
/*tp_init*/ pyrna_property_init,
/*tp_alloc*/ nullptr,
/*tp_new*/ pyrna_prop_new,
/*tp_new*/ pyrna_property_new,
/*tp_free*/ nullptr,
/*tp_is_gc*/ nullptr,
/*tp_bases*/ nullptr,
@@ -7001,7 +7144,7 @@ PyTypeObject pyrna_prop_array_Type = {
/*tp_name*/ "bpy_prop_array",
/*tp_basicsize*/ sizeof(BPy_PropertyArrayRNA),
/*tp_itemsize*/ 0,
/*tp_dealloc*/ (destructor)pyrna_prop_array_dealloc,
/*tp_dealloc*/ nullptr, /* Inherited from #pyrna_prop_Type. */
/*tp_vectorcall_offset*/ 0,
/*tp_getattr*/ nullptr,
/*tp_setattr*/ nullptr,
@@ -7036,9 +7179,9 @@ PyTypeObject pyrna_prop_array_Type = {
/*tp_descr_get*/ nullptr,
/*tp_descr_set*/ nullptr,
/*tp_dictoffset*/ 0,
/*tp_init*/ nullptr,
/*tp_init*/ pyrna_property_array_init,
/*tp_alloc*/ nullptr,
/*tp_new*/ nullptr,
/*tp_new*/ nullptr, /* Inherited from #pyrna_prop_Type. */
/*tp_free*/ nullptr,
/*tp_is_gc*/ nullptr,
/*tp_bases*/ nullptr,
@@ -7057,7 +7200,7 @@ PyTypeObject pyrna_prop_collection_Type = {
/*tp_name*/ "bpy_prop_collection",
/*tp_basicsize*/ sizeof(BPy_PropertyRNA),
/*tp_itemsize*/ 0,
/*tp_dealloc*/ (destructor)pyrna_prop_dealloc,
/*tp_dealloc*/ nullptr, /* Inherited from #pyrna_prop_Type. */
/*tp_vectorcall_offset*/ 0,
/*tp_getattr*/ nullptr,
/*tp_setattr*/ nullptr,
@@ -7092,9 +7235,9 @@ PyTypeObject pyrna_prop_collection_Type = {
/*tp_descr_get*/ nullptr,
/*tp_descr_set*/ nullptr,
/*tp_dictoffset*/ 0,
/*tp_init*/ nullptr,
/*tp_init*/ nullptr, /* Inherited from #pyrna_prop_Type. */
/*tp_alloc*/ nullptr,
/*tp_new*/ nullptr,
/*tp_new*/ nullptr, /* Inherited from #pyrna_prop_Type. */
/*tp_free*/ nullptr,
/*tp_is_gc*/ nullptr,
/*tp_bases*/ nullptr,
@@ -7114,7 +7257,7 @@ static PyTypeObject pyrna_prop_collection_idprop_Type = {
/*tp_name*/ "bpy_prop_collection_idprop",
/*tp_basicsize*/ sizeof(BPy_PropertyRNA),
/*tp_itemsize*/ 0,
/*tp_dealloc*/ (destructor)pyrna_prop_dealloc,
/*tp_dealloc*/ nullptr, /* Inherited from #pyrna_prop_Type. */
/*tp_vectorcall_offset*/ 0,
/*tp_getattr*/ nullptr,
/*tp_setattr*/ nullptr,
@@ -7149,9 +7292,9 @@ static PyTypeObject pyrna_prop_collection_idprop_Type = {
/*tp_descr_get*/ nullptr,
/*tp_descr_set*/ nullptr,
/*tp_dictoffset*/ 0,
/*tp_init*/ nullptr,
/*tp_init*/ nullptr, /* Inherited from #pyrna_prop_Type. */
/*tp_alloc*/ nullptr,
/*tp_new*/ nullptr,
/*tp_new*/ nullptr, /* Inherited from #pyrna_prop_Type. */
/*tp_free*/ nullptr,
/*tp_is_gc*/ nullptr,
/*tp_bases*/ nullptr,
@@ -7165,14 +7308,426 @@ static PyTypeObject pyrna_prop_collection_idprop_Type = {
/*tp_vectorcall*/ nullptr,
};
static PyObject *pyrna_property_new(PyTypeObject *type, PyObject *args, PyObject * /*kwds*/)
{
if (PyTuple_GET_SIZE(args) != 1) {
PyErr_Format(PyExc_TypeError, "bpy_prop.__new__(property): expected a single argument");
return nullptr;
}
PyObject *arg_1 = PyTuple_GET_ITEM(args, 0);
/* Ignore the special 'PyCapsule' argument used only by internal bpy_rna code. */
if (!PyCapsule_CheckExact(arg_1)) {
BPy_PropertyRNA *base = reinterpret_cast<BPy_PropertyRNA *>(arg_1);
/* Error, invalid type given. */
if (!PyType_IsSubtype(Py_TYPE(base), &pyrna_prop_Type)) {
PyErr_Format(
PyExc_TypeError,
"bpy_prop.__new__(property): property type '%.200s' is not a subtype of bpy_prop",
Py_TYPE(base)->tp_name);
return nullptr;
}
/* Same type, simply use the given data. */
if (Py_TYPE(base) == type) {
BLI_assert(base->ptr.has_value());
Py_INCREF(base);
return reinterpret_cast<PyObject *>(base);
}
/* NOTE: Further copy of the 'base' content into the new object will happen in
* #pyrna_property_init. */
}
/* Only allocate the pyobject data, do not construct/initialize anything else. */
PyObject *self = type->tp_alloc(type, 0);
BPy_PropertyRNA *self_property = reinterpret_cast<BPy_PropertyRNA *>(self);
if (self) {
self_property->ptr = std::nullopt;
}
/* Pass on exception & nullptr if tp_alloc fails. */
return self;
}
static int pyrna_property_init(PyObject *self, PyObject *args, PyObject * /*kwds*/)
{
BPy_PropertyRNA *self_property = reinterpret_cast<BPy_PropertyRNA *>(self);
size_t args_num = PyTuple_GET_SIZE(args);
if (args_num != 1) {
PyErr_Format(PyExc_TypeError, "bpy_prop.__init__(self, property): expected a single argument");
return -1;
}
PyObject *arg_1 = PyTuple_GET_ITEM(args, 0);
const PointerRNA *ptr = nullptr;
PropertyRNA *prop = nullptr;
if (PyCapsule_CheckExact(arg_1)) {
/* `bpy_rna` internal code will call object creation with a PyCapsule argument wrapping up a
* PointerRNA and PropertyRNA pointers. */
BPy_PropertyPointerRNA_Reference *pypropptr_rna =
static_cast<BPy_PropertyPointerRNA_Reference *>(
PyCapsule_GetPointer(arg_1, BPy_PropertyPointerRNA_capsule_identifier));
if (pypropptr_rna) {
ptr = pypropptr_rna->ptr;
prop = pypropptr_rna->prop;
}
}
else {
BPy_PropertyRNA *base_property = reinterpret_cast<BPy_PropertyRNA *>(arg_1);
/* Error, invalid type given. */
if (!PyType_IsSubtype(Py_TYPE(base_property), &pyrna_prop_Type)) {
PyErr_Format(
PyExc_TypeError,
"bpy_prop.__init__(self, property): property type '%.200s' is not a subtype of bpy_prop",
Py_TYPE(base_property)->tp_name);
return -1;
}
/* Same object as the 'base' argument (see #pyrna_property_new), nothing to do . */
if (base_property == self_property) {
BLI_assert(self_property->ptr.has_value());
return 0;
}
ptr = &base_property->ptr.value();
prop = base_property->prop;
}
self_property->ptr = *ptr;
self_property->prop = prop;
return 0;
}
static void pyrna_property_dealloc(PyObject *self)
{
/* Save the current exception, if any. */
PyObject *error_type, *error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
BPy_PropertyRNA *self_property = reinterpret_cast<BPy_PropertyRNA *>(self);
#ifdef USE_WEAKREFS
if (self_property->in_weakreflist != nullptr) {
PyObject_ClearWeakRefs(self);
}
#endif
self_property->ptr.~optional();
Py_TYPE(self)->tp_free(self);
/* Restore the saved exception. */
PyErr_Restore(error_type, error_value, error_traceback);
}
static int pyrna_property_array_init(PyObject *self, PyObject *args, PyObject * /*kwds*/)
{
BPy_PropertyArrayRNA *self_property = reinterpret_cast<BPy_PropertyArrayRNA *>(self);
size_t args_num = PyTuple_GET_SIZE(args);
if (args_num != 1) {
PyErr_Format(PyExc_TypeError,
"bpy_prop_array.__init__(self, property): expected a single argument");
return -1;
}
PyObject *arg_1 = PyTuple_GET_ITEM(args, 0);
const PointerRNA *ptr = nullptr;
PropertyRNA *prop = nullptr;
if (PyCapsule_CheckExact(arg_1)) {
/* `bpy_rna` internal code will call object creation with a PyCapsule argument wrapping up a
* PointerRNA and PropertyRNA pointers. */
BPy_PropertyPointerRNA_Reference *pypropptr_rna =
static_cast<BPy_PropertyPointerRNA_Reference *>(
PyCapsule_GetPointer(arg_1, BPy_PropertyPointerRNA_capsule_identifier));
if (pypropptr_rna) {
ptr = pypropptr_rna->ptr;
prop = pypropptr_rna->prop;
}
}
else {
BPy_PropertyArrayRNA *base_property = reinterpret_cast<BPy_PropertyArrayRNA *>(arg_1);
/* Error, invalid type given. */
if (!PyType_IsSubtype(Py_TYPE(base_property), &pyrna_prop_array_Type)) {
PyErr_Format(PyExc_TypeError,
"bpy_prop_array.__init__(self, property): property type '%.200s' is not a "
"subtype of bpy_prop_array",
Py_TYPE(base_property)->tp_name);
return -1;
}
/* Same object as the 'base' argument (see #pyrna_property_new), nothing to do . */
if (base_property == self_property) {
BLI_assert(self_property->ptr.has_value());
return 0;
}
ptr = &base_property->ptr.value();
prop = base_property->prop;
}
self_property->prop = prop;
self_property->arraydim = 0;
self_property->arrayoffset = 0;
self_property->ptr = *ptr;
return 0;
}
#ifdef USE_PYRNA_ITER
/* --- collection iterator: start --- */
/* Wrap RNA collection iterator functions. */
/*
* RNA_property_collection_begin(...)
* RNA_property_collection_next(...)
* RNA_property_collection_end(...)
*/
static PyObject *pyrna_prop_collection_iter_new(PyTypeObject *type,
PyObject * /*args*/,
PyObject * /*kwds*/);
static int pyrna_prop_collection_iter_init(PyObject *self,
PyObject * /*args*/,
PyObject * /*kwds*/);
static void pyrna_prop_collection_iter_dealloc(PyObject *self);
static PyObject *pyrna_prop_collection_iter_next(PyObject *self);
static PyTypeObject pyrna_prop_collection_iter_Type = {
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
/*tp_name*/ "bpy_prop_collection_iter",
/*tp_basicsize*/ sizeof(BPy_PropertyCollectionIterRNA),
/*tp_itemsize*/ 0,
/*tp_dealloc*/ pyrna_prop_collection_iter_dealloc,
/*tp_vectorcall_offset*/ 0,
/*tp_getattr*/ nullptr,
/*tp_setattr*/ nullptr,
/*tp_as_async*/ nullptr,
/*tp_repr*/ nullptr, /* No need to define, sub-classed. */
/*tp_as_number*/ nullptr,
/*tp_as_sequence*/ nullptr,
/*tp_as_mapping*/ nullptr,
/*tp_hash*/ nullptr,
/*tp_call*/ nullptr,
/*tp_str*/ nullptr,
/*tp_getattro*/ PyObject_GenericGetAttr,
/*tp_setattro*/ nullptr,
/*tp_as_buffer*/ nullptr,
/*tp_flags*/ Py_TPFLAGS_DEFAULT,
/*tp_doc*/ nullptr,
/*tp_traverse*/ nullptr,
/*tp_clear*/ nullptr,
/*tp_richcompare*/ nullptr,
# ifdef USE_WEAKREFS
/*tp_weaklistoffset*/ offsetof(BPy_PropertyCollectionIterRNA, in_weakreflist),
# else
/*tp_weaklistoffset*/ 0,
# endif
/*tp_iter*/ PyObject_SelfIter,
/*tp_iternext*/ pyrna_prop_collection_iter_next,
/*tp_methods*/ nullptr,
/*tp_members*/ nullptr,
/*tp_getset*/ nullptr,
/*tp_base*/ nullptr,
/*tp_dict*/ nullptr,
/*tp_descr_get*/ nullptr,
/*tp_descr_set*/ nullptr,
/*tp_dictoffset*/ 0,
/*tp_init*/ pyrna_prop_collection_iter_init,
/*tp_alloc*/ nullptr,
/*tp_new*/ pyrna_prop_collection_iter_new,
/*tp_free*/ nullptr,
/*tp_is_gc*/ nullptr,
/*tp_bases*/ nullptr,
/*tp_mro*/ nullptr,
/*tp_cache*/ nullptr,
/*tp_subclasses*/ nullptr,
/*tp_weaklist*/ nullptr,
/*tp_del*/ nullptr,
/*tp_version_tag*/ 0,
/*tp_finalize*/ nullptr,
/*tp_vectorcall*/ nullptr,
};
static PyObject *pyrna_prop_collection_iter_new(PyTypeObject *type,
PyObject *args,
PyObject * /*kwds*/)
{
if (PyTuple_GET_SIZE(args) != 1) {
PyErr_Format(PyExc_TypeError,
"bpy_prop_collection_iter.__new__(arg): expected a single argument");
return nullptr;
}
PyObject *arg_1 = PyTuple_GET_ITEM(args, 0);
/* Only accept the special 'PyCapsule' argument used by internal bpy_rna code. */
if (!PyCapsule_CheckExact(arg_1)) {
PyErr_Format(PyExc_TypeError,
"bpy_prop_collection_iter.__new__(arg): arg type '%.200s' is not a PyCapsule",
Py_TYPE(arg_1)->tp_name);
return nullptr;
}
/* Only allocate the pyobject data, do not construct/initialize anything else. */
PyObject *self = type->tp_alloc(type, 0);
BPy_PropertyCollectionIterRNA *self_prop_iter =
reinterpret_cast<BPy_PropertyCollectionIterRNA *>(self);
if (self_prop_iter) {
self_prop_iter->iter = std::nullopt;
}
return self;
}
static int pyrna_prop_collection_iter_init(PyObject *self, PyObject *args, PyObject * /*kwds*/)
{
BPy_PropertyCollectionIterRNA *self_prop_iter =
reinterpret_cast<BPy_PropertyCollectionIterRNA *>(self);
size_t args_num = PyTuple_GET_SIZE(args);
if (args_num != 1) {
PyErr_Format(
PyExc_TypeError,
"bpy_prop_collection_iter.__init__(self, arg): expected at most a single argument");
return -1;
}
PyObject *arg_1 = PyTuple_GET_ITEM(args, 0);
const PointerRNA *ptr = nullptr;
PropertyRNA *prop = nullptr;
if (PyCapsule_CheckExact(arg_1)) {
/* `bpy_rna` internal code will call object creation with a PyCapsule argument wrapping up a
* PointerRNA and PropertyRNA pointers. */
BPy_PropertyPointerRNA_Reference *pypropptr_rna =
static_cast<BPy_PropertyPointerRNA_Reference *>(
PyCapsule_GetPointer(arg_1, BPy_PropertyPointerRNA_capsule_identifier));
if (pypropptr_rna) {
ptr = pypropptr_rna->ptr;
prop = pypropptr_rna->prop;
}
}
else {
PyErr_Format(
PyExc_TypeError,
"bpy_prop_collection_iter.__init__(self, arg): arg type '%.200s' is not a PyCapsule",
Py_TYPE(arg_1)->tp_name);
}
if (self_prop_iter->iter.has_value()) {
RNA_property_collection_end(&self_prop_iter->iter.value());
self_prop_iter->iter.reset();
}
self_prop_iter->iter = CollectionPropertyIterator();
RNA_property_collection_begin(
const_cast<PointerRNA *>(ptr), prop, &self_prop_iter->iter.value());
return 0;
}
static void pyrna_prop_collection_iter_dealloc(PyObject *self)
{
/* Save the current exception, if any. */
PyObject *error_type, *error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
BPy_PropertyCollectionIterRNA *self_property = reinterpret_cast<BPy_PropertyCollectionIterRNA *>(
self);
# ifdef USE_WEAKREFS
if (self_property->in_weakreflist != nullptr) {
PyObject_ClearWeakRefs(self);
}
# endif
if (self_property->iter.has_value()) {
RNA_property_collection_end(&self_property->iter.value());
self_property->iter.reset();
}
Py_TYPE(self)->tp_free(self);
/* Restore the saved exception. */
PyErr_Restore(error_type, error_value, error_traceback);
}
static PyObject *pyrna_prop_collection_iter_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
{
/* Pass the PointerRNA and PropertyRNA to `__new__`/`__init__` functions as an opaque PyCapsule
* object. */
BPy_PropertyPointerRNA_Reference prop_ptr{ptr, prop};
PyObject *pypropptr_rna = PyCapsule_New(
&prop_ptr, BPy_PropertyPointerRNA_capsule_identifier, nullptr);
PyObject *self = PyObject_CallOneArg(
reinterpret_cast<PyObject *>(&pyrna_prop_collection_iter_Type), pypropptr_rna);
BPy_PropertyCollectionIterRNA *self_property = reinterpret_cast<BPy_PropertyCollectionIterRNA *>(
self);
BLI_assert(self_property->iter.has_value());
Py_DECREF(pypropptr_rna);
# ifdef USE_WEAKREFS
self_property->in_weakreflist = nullptr;
# endif
return self;
}
static PyObject *pyrna_prop_collection_iter(PyObject *self)
{
BPy_PropertyRNA *self_property = reinterpret_cast<BPy_PropertyRNA *>(self);
return pyrna_prop_collection_iter_CreatePyObject(&self_property->ptr.value(),
self_property->prop);
}
static PyObject *pyrna_prop_collection_iter_next(PyObject *self)
{
BPy_PropertyCollectionIterRNA *self_property = reinterpret_cast<BPy_PropertyCollectionIterRNA *>(
self);
if (self_property->iter->valid == false) {
PyErr_SetNone(PyExc_StopIteration);
return nullptr;
}
PyObject *iter_data = pyrna_struct_CreatePyObject(&self_property->iter->ptr);
# ifdef USE_PYRNA_STRUCT_REFERENCE
if (iter_data) { /* Unlikely, but may fail. */
BPy_StructRNA *iter_data_struct = reinterpret_cast<BPy_StructRNA *>(iter_data);
if (iter_data != Py_None) {
/* hold a reference to the iterator since it may have
* allocated memory 'pyrna' needs. eg: introspecting dynamic enum's. */
/* TODO: we could have an api call to know if this is
* needed since most collections don't */
pyrna_struct_reference_set(iter_data_struct, self);
}
}
# endif /* !USE_PYRNA_STRUCT_REFERENCE */
RNA_property_collection_next(&self_property->iter.value());
return iter_data;
}
/* --- collection iterator: end --- */
#endif /* !USE_PYRNA_ITER */
/** @} */
/*-----------------------BPy_PropertyRNA method def------------------------------*/
/**
* \defgroup BPY RNA Function
*
* @{
*/
static PyObject *pyrna_function_new(PyTypeObject *type, PyObject *args, PyObject * /*kwds*/);
static int pyrna_function_init(PyObject *self, PyObject *args, PyObject * /*kwds*/);
static void pyrna_function_dealloc(PyObject *self);
PyTypeObject pyrna_func_Type = {
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
/*tp_name*/ "bpy_func",
/*tp_basicsize*/ sizeof(BPy_FunctionRNA),
/*tp_itemsize*/ 0,
/*tp_dealloc*/ nullptr,
/*tp_dealloc*/ pyrna_function_dealloc,
/*tp_vectorcall_offset*/ 0,
/*tp_getattr*/ nullptr,
/*tp_setattr*/ nullptr,
@@ -7207,9 +7762,9 @@ PyTypeObject pyrna_func_Type = {
/*tp_descr_get*/ nullptr,
/*tp_descr_set*/ nullptr,
/*tp_dictoffset*/ 0,
/*tp_init*/ nullptr,
/*tp_init*/ pyrna_function_init,
/*tp_alloc*/ nullptr,
/*tp_new*/ nullptr,
/*tp_new*/ pyrna_function_new,
/*tp_free*/ nullptr,
/*tp_is_gc*/ nullptr,
/*tp_bases*/ nullptr,
@@ -7223,134 +7778,93 @@ PyTypeObject pyrna_func_Type = {
/*tp_vectorcall*/ nullptr,
};
#ifdef USE_PYRNA_ITER
/* --- collection iterator: start --- */
/* wrap RNA collection iterator functions */
/*
* RNA_property_collection_begin(...)
* RNA_property_collection_next(...)
* RNA_property_collection_end(...)
*/
static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self);
static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self);
static PyTypeObject pyrna_prop_collection_iter_Type = {
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
/*tp_name*/ "bpy_prop_collection_iter",
/*tp_basicsize*/ sizeof(BPy_PropertyCollectionIterRNA),
/*tp_itemsize*/ 0,
/*tp_dealloc*/ (destructor)pyrna_prop_collection_iter_dealloc,
/*tp_vectorcall_offset*/ 0,
/*tp_getattr*/ nullptr,
/*tp_setattr*/ nullptr,
/*tp_as_async*/ nullptr,
/*tp_repr*/ nullptr, /* No need to define, sub-classed. */
/*tp_as_number*/ nullptr,
/*tp_as_sequence*/ nullptr,
/*tp_as_mapping*/ nullptr,
/*tp_hash*/ nullptr,
/*tp_call*/ nullptr,
/*tp_str*/ nullptr,
/*tp_getattro*/ PyObject_GenericGetAttr,
/*tp_setattro*/ nullptr,
/*tp_as_buffer*/ nullptr,
/*tp_flags*/ Py_TPFLAGS_DEFAULT,
/*tp_doc*/ nullptr,
/*tp_traverse*/ nullptr,
/*tp_clear*/ nullptr,
/*tp_richcompare*/ nullptr,
# ifdef USE_WEAKREFS
/*tp_weaklistoffset*/ offsetof(BPy_PropertyCollectionIterRNA, in_weakreflist),
# else
/*tp_weaklistoffset*/ 0,
# endif
/*tp_iter*/ PyObject_SelfIter,
/*tp_iternext*/ (iternextfunc)pyrna_prop_collection_iter_next,
/*tp_methods*/ nullptr,
/*tp_members*/ nullptr,
/*tp_getset*/ nullptr,
/*tp_base*/ nullptr,
/*tp_dict*/ nullptr,
/*tp_descr_get*/ nullptr,
/*tp_descr_set*/ nullptr,
/*tp_dictoffset*/ 0,
/*tp_init*/ nullptr,
/*tp_alloc*/ nullptr,
/*tp_new*/ nullptr,
/*tp_free*/ nullptr,
/*tp_is_gc*/ nullptr,
/*tp_bases*/ nullptr,
/*tp_mro*/ nullptr,
/*tp_cache*/ nullptr,
/*tp_subclasses*/ nullptr,
/*tp_weaklist*/ nullptr,
/*tp_del*/ nullptr,
/*tp_version_tag*/ 0,
/*tp_finalize*/ nullptr,
/*tp_vectorcall*/ nullptr,
};
static PyObject *pyrna_prop_collection_iter_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
static PyObject *pyrna_function_new(PyTypeObject *type, PyObject *args, PyObject * /*kwds*/)
{
BPy_PropertyCollectionIterRNA *self = PyObject_New(BPy_PropertyCollectionIterRNA,
&pyrna_prop_collection_iter_Type);
# ifdef USE_WEAKREFS
self->in_weakreflist = nullptr;
# endif
RNA_property_collection_begin(ptr, prop, &self->iter);
return (PyObject *)self;
}
static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
{
return pyrna_prop_collection_iter_CreatePyObject(&self->ptr, self->prop);
}
static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self)
{
if (self->iter.valid == false) {
PyErr_SetNone(PyExc_StopIteration);
if (PyTuple_GET_SIZE(args) != 1) {
PyErr_Format(PyExc_TypeError, "bpy_func.__new__(arg): expected a single argument");
return nullptr;
}
BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr);
PyObject *arg_1 = PyTuple_GET_ITEM(args, 0);
# ifdef USE_PYRNA_STRUCT_REFERENCE
if (pyrna) { /* Unlikely, but may fail. */
if ((PyObject *)pyrna != Py_None) {
/* hold a reference to the iterator since it may have
* allocated memory 'pyrna' needs. eg: introspecting dynamic enum's. */
/* TODO: we could have an api call to know if this is
* needed since most collections don't */
pyrna_struct_reference_set(pyrna, (PyObject *)self);
/* Only accept the special 'PyCapsule' argument used by internal bpy_rna code. */
if (!PyCapsule_CheckExact(arg_1)) {
PyErr_Format(PyExc_TypeError,
"bpy_func.__new__(arg): arg type '%.200s' is not a PyCapsule",
Py_TYPE(arg_1)->tp_name);
return nullptr;
}
/* Only allocate the pyobject data, do not construct/initialize anything else. */
PyObject *self = type->tp_alloc(type, 0);
BPy_FunctionRNA *self_function = reinterpret_cast<BPy_FunctionRNA *>(self);
if (self_function) {
self_function->ptr = std::nullopt;
}
return self;
}
static int pyrna_function_init(PyObject *self, PyObject *args, PyObject * /*kwds*/)
{
BPy_FunctionRNA *self_function = reinterpret_cast<BPy_FunctionRNA *>(self);
size_t args_num = PyTuple_GET_SIZE(args);
if (args_num != 1) {
PyErr_Format(PyExc_TypeError,
"bpy_func.__init__(self, arg): expected at most a single argument");
return -1;
}
PyObject *arg_1 = PyTuple_GET_ITEM(args, 0);
const PointerRNA *ptr = nullptr;
FunctionRNA *func = nullptr;
if (PyCapsule_CheckExact(arg_1)) {
/* `bpy_rna` internal code will call object creation with a PyCapsule argument wrapping up a
* PointerRNA and FunctionRNA pointer. */
BPy_FunctionPointerRNA_Reference *pyfuncptr_rna =
static_cast<BPy_FunctionPointerRNA_Reference *>(
PyCapsule_GetPointer(arg_1, BPy_FunctionPointerRNA_capsule_identifier));
if (pyfuncptr_rna) {
ptr = pyfuncptr_rna->ptr;
func = pyfuncptr_rna->func;
}
}
# endif /* !USE_PYRNA_STRUCT_REFERENCE */
RNA_property_collection_next(&self->iter);
return (PyObject *)pyrna;
}
static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self)
{
# ifdef USE_WEAKREFS
if (self->in_weakreflist != nullptr) {
PyObject_ClearWeakRefs((PyObject *)self);
else {
PyErr_Format(PyExc_TypeError,
"bpy_func.__init__(self, arg): arg type '%.200s' is not a PyCapsule",
Py_TYPE(arg_1)->tp_name);
}
# endif
RNA_property_collection_end(&self->iter);
self_function->func = func;
self_function->ptr = *ptr;
PyObject_DEL(self);
return 0;
}
/* --- collection iterator: end --- */
#endif /* !USE_PYRNA_ITER */
static void pyrna_function_dealloc(PyObject *self)
{
/* Save the current exception, if any. */
PyObject *error_type, *error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
BPy_FunctionRNA *self_func = reinterpret_cast<BPy_FunctionRNA *>(self);
#ifdef USE_WEAKREFS
if (self_func->in_weakreflist != nullptr) {
PyObject_ClearWeakRefs(self);
}
#endif
self_func->ptr.~optional();
Py_TYPE(self)->tp_free(self);
/* Restore the saved exception. */
PyErr_Restore(error_type, error_value, error_traceback);
}
/** @} */
static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
{
@@ -7628,51 +8142,50 @@ static PyObject *pyrna_struct_CreatePyObject_from_type(const PointerRNA *ptr,
PyTypeObject *tp,
void **instance)
{
/* Pass the PointerRNA to `__new__`/`__init__` functions as an opaque PyCapsule object. */
PyObject *pyptr_rna = PyCapsule_New(
const_cast<PointerRNA *>(ptr), BPy_capsule_PointerRNA_identifier, nullptr);
BPy_StructRNA *pyrna = nullptr;
if (tp) {
pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0);
#ifdef USE_PYRNA_STRUCT_REFERENCE
/* #PyType_GenericAlloc will have set tracking.
* We only want tracking when `StructRNA.reference` has been set. */
if (pyrna != nullptr) {
PyObject_GC_UnTrack(pyrna);
}
#endif
pyrna = reinterpret_cast<BPy_StructRNA *>(
PyObject_CallOneArg(reinterpret_cast<PyObject *>(tp), pyptr_rna));
}
else {
CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type));
#ifdef USE_PYRNA_STRUCT_REFERENCE
pyrna = (BPy_StructRNA *)PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type);
#else
pyrna = (BPy_StructRNA *)PyObject_New(BPy_StructRNA, &pyrna_struct_Type);
#endif
pyrna = reinterpret_cast<BPy_StructRNA *>(
PyObject_CallOneArg(reinterpret_cast<PyObject *>(&pyrna_struct_Type), pyptr_rna));
}
#ifdef USE_PYRNA_STRUCT_REFERENCE
/* #PyType_GenericAlloc will have set tracking.
* We only want tracking when `StructRNA.reference` has been set. */
/* #PyType_GenericAlloc will have set tracking.
* We only want tracking when `StructRNA.reference` has been set. */
if (pyrna != nullptr) {
PyObject_GC_UnTrack(pyrna);
}
#endif
#ifdef USE_WEAKREFS
if (pyrna != nullptr) {
pyrna->in_weakreflist = nullptr;
}
#endif
if (pyrna != nullptr) {
pyrna->in_weakreflist = nullptr;
}
#endif
if (pyrna == nullptr) {
PyErr_SetString(PyExc_MemoryError, "couldn't create bpy_struct object");
return nullptr;
}
BLI_assert(pyrna->ptr.has_value());
Py_DECREF(pyptr_rna);
/* Blender's instance owns a reference (to avoid Python freeing it). */
if (instance) {
*instance = pyrna;
Py_INCREF(pyrna);
}
pyrna->ptr = *ptr;
#ifdef PYRNA_FREE_SUPPORT
pyrna->freeptr = false;
#endif
@@ -7688,19 +8201,20 @@ static PyObject *pyrna_struct_CreatePyObject_from_type(const PointerRNA *ptr,
id_weakref_pool_add(ptr->owner_id, (BPy_DummyPointerRNA *)pyrna);
}
#endif
return (PyObject *)pyrna;
return reinterpret_cast<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;
}
BPy_StructRNA *pyrna = nullptr;
/* 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;
@@ -7708,24 +8222,23 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
pyrna = static_cast<BPy_StructRNA *>(*instance);
/* Refine may have changed types after the first instance was created. */
if (ptr->type == pyrna->ptr.type) {
if (ptr->type == pyrna->ptr->type) {
Py_INCREF(pyrna);
return (PyObject *)pyrna;
return reinterpret_cast<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
/* Continue as if no instance was available. */
}
PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr);
pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject_from_type(ptr, tp, instance);
PyTypeObject *tp = reinterpret_cast<PyTypeObject *>(pyrna_struct_Subtype(ptr));
pyrna = reinterpret_cast<BPy_StructRNA *>(
pyrna_struct_CreatePyObject_from_type(ptr, tp, instance));
Py_XDECREF(tp); /* `srna` owns, can't hold a reference. */
return (PyObject *)pyrna;
return reinterpret_cast<PyObject *>(pyrna);
}
PyObject *pyrna_struct_CreatePyObject_with_primitive_support(PointerRNA *ptr)
@@ -7751,44 +8264,42 @@ PyObject *pyrna_struct_CreatePyObject_with_primitive_support(PointerRNA *ptr)
PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
{
BPy_PropertyRNA *pyrna;
if (RNA_property_array_check(prop) == 0) {
PyTypeObject *type;
if (RNA_property_type(prop) != PROP_COLLECTION) {
type = &pyrna_prop_Type;
PyTypeObject *type;
if (RNA_property_array_check(prop)) {
type = &pyrna_prop_array_Type;
}
else if (RNA_property_type(prop) == PROP_COLLECTION) {
if (RNA_property_flag(prop) & PROP_IDPROPERTY) {
type = &pyrna_prop_collection_idprop_Type;
}
else {
if ((RNA_property_flag(prop) & PROP_IDPROPERTY) == 0) {
type = &pyrna_prop_collection_Type;
}
else {
type = &pyrna_prop_collection_idprop_Type;
}
type = &pyrna_prop_collection_Type;
}
pyrna = (BPy_PropertyRNA *)PyObject_NEW(BPy_PropertyRNA, type);
#ifdef USE_WEAKREFS
pyrna->in_weakreflist = nullptr;
#endif
}
else {
pyrna = (BPy_PropertyRNA *)PyObject_NEW(BPy_PropertyArrayRNA, &pyrna_prop_array_Type);
((BPy_PropertyArrayRNA *)pyrna)->arraydim = 0;
((BPy_PropertyArrayRNA *)pyrna)->arrayoffset = 0;
#ifdef USE_WEAKREFS
((BPy_PropertyArrayRNA *)pyrna)->in_weakreflist = nullptr;
#endif
type = &pyrna_prop_Type;
}
/* Pass the PointerRNA and PropertyRNA to `__new__`/`__init__` functions as an opaque PyCapsule
* object. */
BPy_PropertyPointerRNA_Reference prop_ptr{ptr, prop};
PyObject *pypropptr_rna = PyCapsule_New(
&prop_ptr, BPy_PropertyPointerRNA_capsule_identifier, nullptr);
BPy_PropertyRNA *pyrna = reinterpret_cast<BPy_PropertyRNA *>(
PyObject_CallOneArg(reinterpret_cast<PyObject *>(type), pypropptr_rna));
if (pyrna == nullptr) {
PyErr_SetString(PyExc_MemoryError, "couldn't create BPy_rna object");
return nullptr;
}
pyrna->ptr = *ptr;
pyrna->prop = prop;
BLI_assert(pyrna->ptr.has_value());
Py_DECREF(pypropptr_rna);
#ifdef USE_WEAKREFS
pyrna->in_weakreflist = nullptr;
#endif
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
if (ptr->owner_id) {
@@ -7812,7 +8323,7 @@ PyObject *pyrna_id_CreatePyObject(ID *id)
bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
{
if (pyrna_id_CheckPyObject(obj)) {
*id = ((BPy_StructRNA *)obj)->ptr.owner_id;
*id = ((BPy_StructRNA *)obj)->ptr->owner_id;
return true;
}
@@ -7822,7 +8333,7 @@ bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
bool pyrna_id_CheckPyObject(PyObject *obj)
{
return BPy_StructRNA_Check(obj) && RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type);
return BPy_StructRNA_Check(obj) && RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr->type);
}
void BPY_rna_init()
@@ -7909,7 +8420,7 @@ PyObject *BPY_rna_module()
PointerRNA ptr = RNA_main_pointer_create(G_MAIN);
pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
rna_module_ptr = &pyrna->ptr;
rna_module_ptr = &pyrna->ptr.value();
return (PyObject *)pyrna;
}
@@ -7945,11 +8456,11 @@ PyObject *BPY_rna_doc()
* This could be a static variable as we only have one `bpy.types` module,
* it just keeps the data isolated to store in the module itself.
*
* This data doesn't change one initialized.
* This data doesn't change once initialized.
*/
struct BPy_TypesModule_State {
/** `RNA_BlenderRNA`. */
PointerRNA ptr;
std::optional<PointerRNA> ptr;
/** `RNA_BlenderRNA.structs`, exposed as `bpy.types` */
PropertyRNA *prop;
};
@@ -7957,6 +8468,8 @@ struct BPy_TypesModule_State {
static PyObject *bpy_types_module_getattro(PyObject *self, PyObject *pyname)
{
BPy_TypesModule_State *state = static_cast<BPy_TypesModule_State *>(PyModule_GetState(self));
BLI_assert(state->ptr.has_value());
PointerRNA newptr;
PyObject *ret;
const char *name = PyUnicode_AsUTF8(pyname);
@@ -7965,7 +8478,8 @@ static PyObject *bpy_types_module_getattro(PyObject *self, PyObject *pyname)
PyErr_SetString(PyExc_AttributeError, "bpy.types: __getattr__ must be a string");
ret = nullptr;
}
else if (RNA_property_collection_lookup_string(&state->ptr, state->prop, name, &newptr)) {
else if (RNA_property_collection_lookup_string(&state->ptr.value(), state->prop, name, &newptr))
{
ret = pyrna_struct_Subtype(&newptr);
if (ret == nullptr) {
PyErr_Format(PyExc_RuntimeError,
@@ -7990,9 +8504,11 @@ static PyObject *bpy_types_module_getattro(PyObject *self, PyObject *pyname)
static PyObject *bpy_types_module_dir(PyObject *self)
{
BPy_TypesModule_State *state = static_cast<BPy_TypesModule_State *>(PyModule_GetState(self));
BLI_assert(state->ptr.has_value());
PyObject *ret = PyList_New(0);
RNA_PROP_BEGIN (&state->ptr, itemptr, state->prop) {
RNA_PROP_BEGIN (&state->ptr.value(), itemptr, state->prop) {
StructRNA *srna = static_cast<StructRNA *>(itemptr.data);
PyList_APPEND(ret, PyUnicode_FromString(RNA_struct_identifier(srna)));
}
@@ -8023,6 +8539,19 @@ static PyMethodDef bpy_types_module_methods[] = {
# pragma GCC diagnostic pop
#endif
static void bpy_types_module_free(void *self)
{
/* Module's `m_free` is quite different from `PyTypeObject` `tp_free`. It does not have to free
* python-allocated memory (like the module state itself), but only memory managed outside of
* Python. In that sense, it is way closer to `tp_finalize`. */
PyObject *submodule = static_cast<PyObject *>(self);
BPy_TypesModule_State *state = static_cast<BPy_TypesModule_State *>(
PyModule_GetState(submodule));
state->ptr.~optional();
}
PyDoc_STRVAR(
/* Wrap. */
bpy_types_module_doc,
@@ -8036,7 +8565,7 @@ static PyModuleDef bpy_types_module_def = {
/*m_slots*/ nullptr,
/*m_traverse*/ nullptr,
/*m_clear*/ nullptr,
/*m_free*/ nullptr,
/*m_free*/ bpy_types_module_free,
};
PyObject *BPY_rna_types()
@@ -8046,7 +8575,7 @@ PyObject *BPY_rna_types()
PyModule_GetState(submodule));
state->ptr = RNA_blender_rna_pointer_create();
state->prop = RNA_struct_find_property(&state->ptr, "structs");
state->prop = RNA_struct_find_property(&state->ptr.value(), "structs");
/* Internal base types we have no other accessors for. */
{
@@ -8082,6 +8611,7 @@ void BPY_rna_types_finalize_external_types(PyObject *submodule)
BPy_TypesModule_State *state = static_cast<BPy_TypesModule_State *>(
PyModule_GetState(submodule));
BLI_assert(state->ptr.has_value());
PyObject *arg_key, *arg_value;
Py_ssize_t arg_pos = 0;
@@ -8096,7 +8626,8 @@ void BPY_rna_types_finalize_external_types(PyObject *submodule)
"Members of bpy_types.py which are not StructRNA sub-classes must use a \"_\" prefix!");
PointerRNA newptr;
if (RNA_property_collection_lookup_string(&state->ptr, state->prop, key_str, &newptr)) {
if (RNA_property_collection_lookup_string(&state->ptr.value(), state->prop, key_str, &newptr))
{
StructRNA *srna = srna_from_ptr(&newptr);
/* Within the Python logic of `./scripts/modules/bpy_types.py`
* it's possible this was already initialized. */
@@ -8159,7 +8690,7 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *e
return nullptr;
}
if (py_srna->ptr.type != &RNA_Struct) {
if (py_srna->ptr->type != &RNA_Struct) {
PyErr_Format(PyExc_TypeError,
"%.200s, bl_rna attribute not a RNA_Struct, on '%.200s'' instance",
error_prefix,
@@ -8168,7 +8699,7 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *e
return nullptr;
}
srna = static_cast<StructRNA *>(py_srna->ptr.data);
srna = static_cast<StructRNA *>(py_srna->ptr->data);
Py_DECREF(py_srna);
return srna;
@@ -8177,7 +8708,7 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *e
const PointerRNA *pyrna_struct_as_ptr(PyObject *py_obj, const StructRNA *srna)
{
BPy_StructRNA *bpy_srna = (BPy_StructRNA *)py_obj;
if (!BPy_StructRNA_Check(py_obj) || !RNA_struct_is_a(bpy_srna->ptr.type, srna)) {
if (!BPy_StructRNA_Check(py_obj) || !RNA_struct_is_a(bpy_srna->ptr->type, srna)) {
PyErr_Format(PyExc_TypeError,
"Expected a \"bpy.types.%.200s\" not a \"%.200s\"",
RNA_struct_identifier(srna),
@@ -8185,7 +8716,7 @@ const PointerRNA *pyrna_struct_as_ptr(PyObject *py_obj, const StructRNA *srna)
return nullptr;
}
PYRNA_STRUCT_CHECK_OBJ(bpy_srna);
return &bpy_srna->ptr;
return &bpy_srna->ptr.value();
}
const PointerRNA *pyrna_struct_as_ptr_or_null(PyObject *py_obj, const StructRNA *srna)
@@ -8775,7 +9306,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
py_class_instance = nullptr;
}
else {
#if 1
#if 0
/* Skip the code below and call init directly on the allocated 'py_srna'
* otherwise __init__() always needs to take a second self argument, see pyrna_struct_new().
* Although this is annoying to have to implement a part of Python's
@@ -8817,10 +9348,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
* None of Blender's default scripts use __init__ but it's nice to call it
* for general correctness. just to note why this is here when it could be safely removed.
*/
args = PyTuple_New(1);
PyTuple_SET_ITEM(args, 0, py_srna);
py_class_instance = PyObject_Call(py_class, args, nullptr);
Py_DECREF(args);
py_class_instance = PyObject_CallOneArg(reinterpret_cast<PyObject *>(py_class), py_srna);
rna_disallow_writes = prev_write;
@@ -8829,6 +9357,8 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if (py_class_instance == nullptr) {
err = -1; /* So the error is not overridden below. */
}
Py_DECREF(py_srna);
}
}
@@ -9056,7 +9586,7 @@ static void bpy_class_free(void *pyob_ptr)
}
}
#endif
Py_DECREF((PyObject *)pyob_ptr);
Py_DECREF(self);
PyGILState_Release(gilstate);
}
@@ -9245,12 +9775,7 @@ static PyObject *pyrna_register_class(PyObject * /*self*/, PyObject *py_class)
/* Old srna still references us, keep the check in case registering somehow can free it. */
if (PyObject *old_py_class = static_cast<PyObject *>(RNA_struct_py_type_get(srna))) {
RNA_struct_py_type_set(srna, nullptr);
#if 0
/* Should be able to do this XXX since the old RNA adds a new ref. */
Py_DECREF(old_py_class);
#else
UNUSED_VARS(old_py_class);
#endif
}
/* Can't use this because it returns a dict proxy

View File

@@ -8,6 +8,8 @@
#pragma once
#include <optional>
/* --- bpy build options --- */
#include "intern/rna_internal_types.hh"
#ifdef WITH_PYTHON_SAFETY
@@ -103,8 +105,8 @@ extern PyTypeObject pyrna_func_Type;
} \
(void)0
#define PYRNA_STRUCT_IS_VALID(pysrna) (LIKELY(((BPy_StructRNA *)(pysrna))->ptr.type != NULL))
#define PYRNA_PROP_IS_VALID(pysrna) (LIKELY(((BPy_PropertyRNA *)(pysrna))->ptr.type != NULL))
#define PYRNA_STRUCT_IS_VALID(pysrna) (LIKELY(((BPy_StructRNA *)(pysrna))->ptr->type != NULL))
#define PYRNA_PROP_IS_VALID(pysrna) (LIKELY(((BPy_PropertyRNA *)(pysrna))->ptr->type != NULL))
/* 'in_weakreflist' MUST be aligned */
@@ -113,7 +115,8 @@ struct BPy_DummyPointerRNA {
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
PointerRNA ptr;
std::optional<PointerRNA> ptr;
};
struct BPy_StructRNA {
@@ -121,7 +124,9 @@ struct BPy_StructRNA {
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
PointerRNA ptr;
std::optional<PointerRNA> ptr;
#ifdef USE_PYRNA_STRUCT_REFERENCE
/* generic PyObject we hold a reference to, example use:
* hold onto the collection iterator to prevent it from freeing allocated data we may use */
@@ -139,18 +144,25 @@ struct BPy_PropertyRNA {
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
PointerRNA ptr;
std::optional<PointerRNA> ptr;
PropertyRNA *prop;
};
struct BPy_PropertyArrayRNA {
PyObject_HEAD /* Required Python macro. */
/* START Must match #BPy_PropertyRNA. */
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
PointerRNA ptr;
std::optional<PointerRNA> ptr;
PropertyRNA *prop;
/* END Must match #BPy_PropertyRNA. */
/* Arystan: this is a hack to allow sub-item r/w access like: face.uv[n][m] */
/** Array dimension, e.g: 0 for face.uv, 2 for face.uv[n][m], etc. */
int arraydim;
@@ -165,7 +177,7 @@ struct BPy_PropertyCollectionIterRNA {
#endif
/* collection iterator specific parts */
CollectionPropertyIterator iter;
std::optional<CollectionPropertyIterator> iter;
};
struct BPy_FunctionRNA {
@@ -173,7 +185,8 @@ struct BPy_FunctionRNA {
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
PointerRNA ptr;
std::optional<PointerRNA> ptr;
FunctionRNA *func;
};

View File

@@ -338,7 +338,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
PYRNA_STRUCT_CHECK_OBJ(self);
if (pyrna_struct_keyframe_parse(&self->ptr,
if (pyrna_struct_keyframe_parse(&self->ptr.value(),
args,
kw,
"s|$ifsO!s:bpy_struct.keyframe_insert()",
@@ -369,13 +369,13 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
cfra);
if (self->ptr.type == &RNA_NlaStrip) {
if (self->ptr->type == &RNA_NlaStrip) {
/* Handle special properties for NLA Strips, whose F-Curves are stored on the
* strips themselves. These are stored separately or else the properties will
* not have any effect.
*/
PointerRNA &ptr = self->ptr;
PointerRNA &ptr = *self->ptr;
PropertyRNA *prop = nullptr;
const char *prop_name;
@@ -402,12 +402,12 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
}
}
else {
BLI_assert(BKE_id_is_in_global_main(self->ptr.owner_id));
BLI_assert(BKE_id_is_in_global_main(self->ptr->owner_id));
const std::optional<blender::StringRefNull> channel_group = group_name ?
std::optional(group_name) :
std::nullopt;
PointerRNA id_pointer = RNA_id_pointer_create(self->ptr.owner_id);
PointerRNA id_pointer = RNA_id_pointer_create(self->ptr->owner_id);
CombinedKeyingResult combined_result = insert_keyframes(G_MAIN,
&id_pointer,
channel_group,
@@ -476,7 +476,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
PYRNA_STRUCT_CHECK_OBJ(self);
if (pyrna_struct_keyframe_parse(&self->ptr,
if (pyrna_struct_keyframe_parse(&self->ptr.value(),
args,
kw,
"s|$ifsOs!:bpy_struct.keyframe_delete()",
@@ -496,13 +496,13 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
BKE_reports_init(&reports, RPT_STORE);
if (self->ptr.type == &RNA_NlaStrip) {
if (self->ptr->type == &RNA_NlaStrip) {
/* Handle special properties for NLA Strips, whose F-Curves are stored on the
* strips themselves. These are stored separately or else the properties will
* not have any effect.
*/
PointerRNA ptr = self->ptr;
PointerRNA ptr = *self->ptr;
PropertyRNA *prop = nullptr;
const char *prop_name;
@@ -557,7 +557,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
rna_path.index = std::nullopt;
}
result = (blender::animrig::delete_keyframe(
G.main, &reports, self->ptr.owner_id, rna_path, cfra) != 0);
G.main, &reports, self->ptr->owner_id, rna_path, cfra) != 0);
}
MEM_freeN((void *)path_full);
@@ -593,7 +593,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
}
if (pyrna_struct_anim_args_parse(
&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1)
&self->ptr.value(), "bpy_struct.driver_add():", path, &path_full, &index) == -1)
{
return nullptr;
}
@@ -605,7 +605,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
BKE_reports_init(&reports, RPT_STORE);
result = ANIM_add_driver(&reports,
(ID *)self->ptr.owner_id,
self->ptr->owner_id,
path_full,
index,
CREATEDRIVER_WITH_FMODIFIER,
@@ -616,7 +616,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
}
if (result) {
ID *id = self->ptr.owner_id;
ID *id = self->ptr->owner_id;
AnimData *adt = BKE_animdata_from_id(id);
FCurve *fcu;
@@ -677,7 +677,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
}
if (pyrna_struct_anim_args_parse_no_resolve_fallback(
&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1)
&self->ptr.value(), "bpy_struct.driver_remove():", path, &path_full, &index) == -1)
{
return nullptr;
}
@@ -687,7 +687,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
BKE_reports_init(&reports, RPT_STORE);
result = ANIM_remove_driver(self->ptr.owner_id, path_full, index);
result = ANIM_remove_driver(self->ptr->owner_id, path_full, index);
if (path != path_full) {
MEM_freeN((void *)path_full);

View File

@@ -182,8 +182,8 @@ static PyObject *bpy_rna_data_context_enter(BPy_DataContext *self)
static PyObject *bpy_rna_data_context_exit(BPy_DataContext *self, PyObject * /*args*/)
{
BKE_main_free(static_cast<Main *>(self->data_rna->ptr.data));
RNA_POINTER_INVALIDATE(&self->data_rna->ptr);
BKE_main_free(static_cast<Main *>(self->data_rna->ptr->data));
RNA_POINTER_INVALIDATE(&self->data_rna->ptr.value());
Py_RETURN_NONE;
}

View File

@@ -78,7 +78,7 @@ bool pyrna_driver_is_equal_anim_rna(const PathResolvedRNA *anim_rna, const PyObj
{
if (BPy_StructRNA_Check(py_anim_rna)) {
const PointerRNA *ptr_a = &anim_rna->ptr;
const PointerRNA *ptr_b = &(((const BPy_StructRNA *)py_anim_rna)->ptr);
const PointerRNA *ptr_b = &reinterpret_cast<const BPy_StructRNA *>(py_anim_rna)->ptr.value();
if ((ptr_a->owner_id == ptr_b->owner_id) && (ptr_a->type == ptr_b->type) &&
(ptr_a->data == ptr_b->data))

View File

@@ -49,10 +49,10 @@ static int py_rna_gizmo_parse(PyObject *o, void *p)
{
/* No type checking (this is `self` not a user defined argument). */
BLI_assert(BPy_StructRNA_Check(o));
BLI_assert(RNA_struct_is_a(((const BPy_StructRNA *)o)->ptr.type, &RNA_Gizmo));
BLI_assert(RNA_struct_is_a(((const BPy_StructRNA *)o)->ptr->type, &RNA_Gizmo));
wmGizmo **gz_p = static_cast<wmGizmo **>(p);
*gz_p = static_cast<wmGizmo *>(((const BPy_StructRNA *)o)->ptr.data);
*gz_p = static_cast<wmGizmo *>(((const BPy_StructRNA *)o)->ptr->data);
return 1;
}

View File

@@ -61,7 +61,7 @@ PyDoc_STRVAR(
static PyObject *bpy_rna_region_as_string(PyObject *self, PyObject *args, PyObject *kwds)
{
BPy_StructRNA *pyrna = (BPy_StructRNA *)self;
Text *text = static_cast<Text *>(pyrna->ptr.data);
Text *text = static_cast<Text *>(pyrna->ptr->data);
/* Parse the region range. */
TextRegion region;
@@ -128,7 +128,7 @@ PyDoc_STRVAR(
static PyObject *bpy_rna_region_from_string(PyObject *self, PyObject *args, PyObject *kwds)
{
BPy_StructRNA *pyrna = (BPy_StructRNA *)self;
Text *text = static_cast<Text *>(pyrna->ptr.data);
Text *text = static_cast<Text *>(pyrna->ptr->data);
/* Parse the region range. */
const char *buf;

View File

@@ -28,7 +28,7 @@ PyDoc_STRVAR(
static PyObject *bpy_rna_uilayout_introspect(PyObject *self)
{
BPy_StructRNA *pyrna = (BPy_StructRNA *)self;
uiLayout *layout = static_cast<uiLayout *>(pyrna->ptr.data);
uiLayout *layout = static_cast<uiLayout *>(pyrna->ptr->data);
const char *expr = UI_layout_introspect(layout);
PyObject *main_mod = PyC_MainModule_Backup();