|
|
|
|
@@ -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) = ¶m->ptr;
|
|
|
|
|
else if (RNA_struct_is_a(param->ptr->type, ptr_type)) {
|
|
|
|
|
*((PointerRNA **)data) = ¶m->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
|
|
|
|
|
|