Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/python/intern/bpy_rna.c')
-rw-r--r--source/blender/python/intern/bpy_rna.c360
1 files changed, 243 insertions, 117 deletions
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index a0df8988068..735df7aeb10 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -37,6 +37,12 @@
#include "RNA_types.h"
+#include "BLI_dynstr.h"
+#include "BLI_string.h"
+#include "BLI_listbase.h"
+#include "BLI_math_rotation.h"
+#include "BLI_utildefines.h"
+
#include "BPY_extern.h"
#include "bpy_rna.h"
@@ -50,12 +56,6 @@
# include "MEM_guardedalloc.h"
#endif
-#include "BLI_dynstr.h"
-#include "BLI_string.h"
-#include "BLI_listbase.h"
-#include "BLI_math_rotation.h"
-#include "BLI_utildefines.h"
-
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
# include "BLI_ghash.h"
#endif
@@ -250,7 +250,7 @@ static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_size(weakinfo_hash));
#endif
- while (!BLI_ghashIterator_isDone(&weakinfo_hash_iter)) {
+ while (BLI_ghashIterator_notDone(&weakinfo_hash_iter)) {
PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter);
PyObject *item = PyWeakref_GET_OBJECT(weakref);
if (item != Py_None) {
@@ -309,9 +309,9 @@ void BPY_id_release(struct ID *id)
}
#ifdef USE_PEDANTIC_WRITE
-static short rna_disallow_writes = FALSE;
+static bool rna_disallow_writes = false;
-static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
+static bool rna_id_write_error(PointerRNA *ptr, PyObject *key)
{
ID *id = ptr->id.data;
if (id) {
@@ -329,30 +329,30 @@ static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
"%.200s, %.200s datablock, error setting %.200s.%.200s",
id->name + 2, idtype, RNA_struct_identifier(ptr->type), pyname);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
#endif /* USE_PEDANTIC_WRITE */
#ifdef USE_PEDANTIC_WRITE
-int pyrna_write_check(void)
+bool pyrna_write_check(void)
{
return !rna_disallow_writes;
}
-void pyrna_write_set(int val)
+void pyrna_write_set(bool val)
{
rna_disallow_writes = !val;
}
#else /* USE_PEDANTIC_WRITE */
-int pyrna_write_check(void)
+bool pyrna_write_check(void)
{
- return TRUE;
+ return true;
}
-void pyrna_write_set(int UNUSED(val))
+void pyrna_write_set(bool UNUSED(val))
{
/* nothing */
}
@@ -644,7 +644,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
- PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, FALSE);
+ PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret = mat_cb; /* return the matrix instead */
}
@@ -655,7 +655,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
- PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, FALSE);
+ PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret = mat_cb; /* return the matrix instead */
}
@@ -1123,7 +1123,7 @@ static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
{
EnumPropertyItem *item;
const char *result;
- int free = FALSE;
+ int free = false;
RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
if (item) {
@@ -1187,7 +1187,7 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_
return -1;
}
- if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0) {
+ if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
return -1;
}
@@ -1202,7 +1202,7 @@ static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObj
{
EnumPropertyItem *item;
int ret;
- int free = FALSE;
+ int free = false;
*r_value = 0;
@@ -1282,7 +1282,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
}
else {
EnumPropertyItem *enum_item;
- int free = FALSE;
+ int free = false;
/* don't throw error here, can't trust blender 100% to give the
* right values, python code should not generate error for that */
@@ -1427,7 +1427,9 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
{
arg_name = RNA_property_identifier(prop);
- if (strcmp(arg_name, "rna_type") == 0) continue;
+ if (STREQ(arg_name, "rna_type")) {
+ continue;
+ }
if (kw == NULL) {
PyErr_Format(PyExc_TypeError,
@@ -1478,7 +1480,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
}
-static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
+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;
@@ -1510,12 +1512,18 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
/* prefer not to have an exception here
* however so many poll functions return None or a valid Object.
* its a hassle to convert these into a bool before returning, */
- if (RNA_property_flag(prop) & PROP_OUTPUT)
+ if (RNA_property_flag(prop) & PROP_OUTPUT) {
param = PyObject_IsTrue(value);
- else
+ }
+ else {
param = PyLong_AsLong(value);
- if (param < 0) {
+ if (UNLIKELY(param & ~1)) { /* only accept 0/1 */
+ param = -1; /* error out below */
+ }
+ }
+
+ if (param == -1) {
PyErr_Format(PyExc_TypeError,
"%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
error_prefix, RNA_struct_identifier(ptr->type),
@@ -1617,9 +1625,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
}
else {
-
/* Unicode String */
-
#ifdef USE_STRING_COERCE
PyObject *value_coerce = NULL;
if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
@@ -1628,12 +1634,6 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
else {
param = _PyUnicode_AsString(value);
-#ifdef WITH_INTERNATIONAL
- if (subtype == PROP_TRANSLATE) {
- param = IFACE_(param);
- }
-#endif /* WITH_INTERNATIONAL */
-
}
#else /* USE_STRING_COERCE */
param = _PyUnicode_AsString(value);
@@ -1676,13 +1676,13 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
/* type checkins is done by each function */
if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
/* set of enum items, concatenate all values with OR */
- if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) {
+ if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) {
return -1;
}
}
else {
/* simple enum string */
- if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) {
+ if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) {
return -1;
}
}
@@ -1771,7 +1771,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
else {
BPy_StructRNA *param = (BPy_StructRNA *)value;
- int raise_error = FALSE;
+ bool raise_error = false;
if (data) {
if (flag & PROP_RNAPTR) {
@@ -1798,7 +1798,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
*((void **)data) = param->ptr.data;
}
else {
- raise_error = TRUE;
+ raise_error = true;
}
}
else {
@@ -2189,7 +2189,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
else {
PyObject *keylib = PyTuple_GET_ITEM(key, 1);
Library *lib;
- int found = FALSE;
+ bool found = false;
if (keylib == Py_None) {
lib = NULL;
@@ -2225,8 +2225,8 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop)
{
ID *id = itemptr.data; /* always an ID */
- if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) {
- found = TRUE;
+ if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) {
+ found = true;
if (r_ptr) {
*r_ptr = itemptr;
}
@@ -2236,7 +2236,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
RNA_PROP_END;
/* we may want to fail silently as with collection.get() */
- if ((found == FALSE) && err_not_found) {
+ if ((found == false) && err_not_found) {
/* only runs for getitem access so use fixed string */
PyErr_SetString(PyExc_KeyError,
"bpy_prop_collection[key, lib]: not found");
@@ -2249,7 +2249,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
}
static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key,
- const char *err_prefix, const short err_not_found)
+ const char *err_prefix, const bool err_not_found)
{
PointerRNA ptr;
const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr);
@@ -2442,7 +2442,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
else if (PyTuple_Check(key)) {
/* special case, for ID datablocks we */
return pyrna_prop_collection_subscript_str_lib_pair(self, key,
- "bpy_prop_collection[id, lib]", TRUE);
+ "bpy_prop_collection[id, lib]", true);
}
else {
PyErr_Format(PyExc_TypeError,
@@ -2859,7 +2859,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
if (PyTuple_Check(key)) {
/* special case, for ID datablocks we */
return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key,
- "(id, lib) in bpy_prop_collection", FALSE, NULL);
+ "(id, lib) in bpy_prop_collection", false, NULL);
}
else {
@@ -3119,6 +3119,33 @@ static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *arg
return PyBool_FromLong(RNA_property_is_set(&self->ptr, prop));
}
+PyDoc_STRVAR(pyrna_struct_property_unset_doc,
+".. method:: property_unset(property)\n"
+"\n"
+" Unset a property, will use default value afterward.\n"
+);
+static PyObject *pyrna_struct_property_unset(BPy_StructRNA *self, PyObject *args)
+{
+ PropertyRNA *prop;
+ const char *name;
+
+ PYRNA_STRUCT_CHECK_OBJ(self);
+
+ if (!PyArg_ParseTuple(args, "s:property_unset", &name))
+ return NULL;
+
+ if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.property_unset(\"%.200s\") not found",
+ RNA_struct_identifier(self->ptr.type), name);
+ return NULL;
+ }
+
+ RNA_property_unset(&self->ptr, prop);
+
+ Py_RETURN_NONE;
+}
+
PyDoc_STRVAR(pyrna_struct_is_property_hidden_doc,
".. method:: is_property_hidden(property)\n"
"\n"
@@ -3465,7 +3492,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
}
else if (name[0] == '_') { /* rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups */
/* annoying exception, maybe we need to have different types for this... */
- if ((strcmp(name, "__getitem__") == 0 || strcmp(name, "__setitem__") == 0) && !RNA_struct_idprops_check(self->ptr.type)) {
+ if ((STREQ(name, "__getitem__") || STREQ(name, "__setitem__")) && !RNA_struct_idprops_check(self->ptr.type)) {
PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
ret = NULL;
}
@@ -4199,7 +4226,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
}
else if (PyTuple_Check(key_ob)) {
PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair(self, key_ob,
- "bpy_prop_collection.get((id, lib))", FALSE);
+ "bpy_prop_collection.get((id, lib))", false);
if (ret) {
return ret;
}
@@ -4259,25 +4286,33 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key
return PyLong_FromLong(index);
}
-static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr,
+static bool foreach_attr_type(BPy_PropertyRNA *self, const char *attr,
/* values to assign */
- RawPropertyType *raw_type, int *attr_tot, int *attr_signed)
+ RawPropertyType *raw_type, int *attr_tot, bool *attr_signed)
{
PropertyRNA *prop;
+ bool attr_ok = true;
*raw_type = PROP_RAW_UNSET;
*attr_tot = 0;
- *attr_signed = FALSE;
+ *attr_signed = false;
/* note: this is fail with zero length lists, so don't let this get caled in that case */
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop)
{
prop = RNA_struct_find_property(&itemptr, attr);
- *raw_type = RNA_property_raw_type(prop);
- *attr_tot = RNA_property_array_length(&itemptr, prop);
- *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? FALSE : TRUE;
+ if (prop) {
+ *raw_type = RNA_property_raw_type(prop);
+ *attr_tot = RNA_property_array_length(&itemptr, prop);
+ *attr_signed = (RNA_property_subtype(prop) != PROP_UNSIGNED);
+ }
+ else {
+ attr_ok = false;
+ }
break;
}
RNA_PROP_END;
+
+ return attr_ok;
}
/* pyrna_prop_collection_foreach_get/set both use this */
@@ -4285,7 +4320,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
/* values to assign */
const char **attr, PyObject **seq, int *tot, int *size,
- RawPropertyType *raw_type, int *attr_tot, int *attr_signed
+ RawPropertyType *raw_type, int *attr_tot, bool *attr_signed
)
{
#if 0
@@ -4293,18 +4328,30 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
int target_tot;
#endif
- *size = *attr_tot = *attr_signed = FALSE;
+ *size = *attr_tot = 0;
+ *attr_signed = false;
*raw_type = PROP_RAW_UNSET;
- if (!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) {
- PyErr_SetString(PyExc_TypeError, "foreach_get(attr, sequence) expects a string and a sequence");
+ if (!PyArg_ParseTuple(args, "sO:foreach_get/set", attr, seq)) {
+ return -1;
+ }
+
+ if (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq)) {
+ PyErr_Format(PyExc_TypeError,
+ "foreach_get/set expected second argument to be a sequence or buffer, not a %.200s",
+ Py_TYPE(*seq)->tp_name);
return -1;
}
*tot = PySequence_Size(*seq); /* TODO - buffer may not be a sequence! array.array() is tho. */
if (*tot > 0) {
- foreach_attr_type(self, *attr, raw_type, attr_tot, attr_signed);
+ if (!foreach_attr_type(self, *attr, raw_type, attr_tot, attr_signed)) {
+ PyErr_Format(PyExc_AttributeError,
+ "foreach_get/set '%.200s.%200s[...]' elements have no attribute '%.200s'",
+ RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), *attr);
+ return -1;
+ }
*size = RNA_raw_type_sizeof(*raw_type);
#if 0 /* works fine but not strictly needed, we could allow RNA_property_collection_raw_* to do the checks */
@@ -4338,7 +4385,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
return 0;
}
-static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
+static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
{
char f = format ? *format : 'B'; /* B is assumed when not set */
@@ -4366,16 +4413,18 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, cons
static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
{
PyObject *item = NULL;
- int i = 0, ok = 0, buffer_is_compat;
+ int i = 0, ok = 0;
+ bool buffer_is_compat;
void *array = NULL;
/* get/set both take the same args currently */
const char *attr;
PyObject *seq;
- int tot, size, attr_tot, attr_signed;
+ int tot, size, attr_tot;
+ bool attr_signed;
RawPropertyType raw_type;
- if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0)
+ if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) == -1)
return NULL;
if (tot == 0)
@@ -4384,7 +4433,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
if (set) { /* get the array from python */
- buffer_is_compat = FALSE;
+ buffer_is_compat = false;
if (PyObject_CheckBuffer(seq)) {
Py_buffer buf;
PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
@@ -4435,7 +4484,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
}
}
else {
- buffer_is_compat = FALSE;
+ buffer_is_compat = false;
if (PyObject_CheckBuffer(seq)) {
Py_buffer buf;
PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
@@ -4515,7 +4564,7 @@ PyDoc_STRVAR(pyrna_prop_collection_foreach_get_doc,
"\n"
" .. code-block:: python\n"
"\n"
-" collection.foreach_get(someseq, attr)\n"
+" collection.foreach_get(attr, someseq)\n"
"\n"
" # Python equivalent\n"
" for i in range(len(seq)): someseq[i] = getattr(collection, attr)\n"
@@ -4535,7 +4584,7 @@ PyDoc_STRVAR(pyrna_prop_collection_foreach_set_doc,
"\n"
" .. code-block:: python\n"
"\n"
-" collection.foreach_set(seq, attr)\n"
+" collection.foreach_set(attr, seq)\n"
"\n"
" # Python equivalent\n"
" for i in range(len(seq)): setattr(collection[i], attr, seq[i])\n"
@@ -4611,6 +4660,7 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"driver_remove", (PyCFunction)pyrna_struct_driver_remove, METH_VARARGS, pyrna_struct_driver_remove_doc},
{"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, pyrna_struct_is_property_set_doc},
+ {"property_unset", (PyCFunction)pyrna_struct_property_unset, METH_VARARGS, pyrna_struct_property_unset_doc},
{"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, pyrna_struct_is_property_hidden_doc},
{"path_resolve", (PyCFunction)pyrna_struct_path_resolve, METH_VARARGS, pyrna_struct_path_resolve_doc},
{"path_from_id", (PyCFunction)pyrna_struct_path_from_id, METH_VARARGS, pyrna_struct_path_from_id_doc},
@@ -4618,8 +4668,14 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
/* experimental */
+ /* unused for now */
+#if 0
{"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, NULL},
{"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, NULL},
+
+ {"callback_add", (PyCFunction)pyrna_callback_classmethod_add, METH_VARARGS | METH_CLASS, NULL},
+ {"callback_remove", (PyCFunction)pyrna_callback_classmethod_remove, METH_VARARGS | METH_CLASS, NULL},
+#endif
{NULL, NULL, 0, NULL}
};
@@ -4913,7 +4969,7 @@ static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_look
while (PyDict_Next(dict, &pos, &key, &value)) {
if (PyUnicode_Check(key)) {
- if (strcmp(key_lookup, _PyUnicode_AsString(key)) == 0) {
+ if (STREQ(key_lookup, _PyUnicode_AsString(key))) {
return value;
}
}
@@ -4933,7 +4989,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
ParameterIterator iter;
PropertyRNA *parm;
PyObject *ret, *item;
- int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0, kw_arg;
+ int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0;
+ bool kw_arg;
PropertyRNA *pret_single = NULL;
void *retdata_single = NULL;
@@ -5014,7 +5071,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
if (i < pyargs_len) {
item = PyTuple_GET_ITEM(args, i);
- kw_arg = FALSE;
+ kw_arg = false;
}
else if (kw != NULL) {
#if 0
@@ -5025,7 +5082,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
if (item)
kw_tot++; /* make sure invalid keywords are not given */
- kw_arg = TRUE;
+ kw_arg = true;
}
i++; /* current argument */
@@ -5062,7 +5119,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
char error_prefix[512];
PyErr_Clear(); /* re-raise */
- if (kw_arg == TRUE)
+ if (kw_arg == true)
BLI_snprintf(error_prefix, sizeof(error_prefix),
"%.200s.%.200s(): error with keyword argument \"%.200s\" - ",
RNA_struct_identifier(self_ptr->type),
@@ -5097,12 +5154,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
DynStr *good_args = BLI_dynstr_new();
const char *arg_name, *bad_args_str, *good_args_str;
- int found = FALSE, first = TRUE;
+ bool found = false, first = true;
while (PyDict_Next(kw, &pos, &key, &value)) {
arg_name = _PyUnicode_AsString(key);
- found = FALSE;
+ found = false;
if (arg_name == NULL) { /* unlikely the argname is not a string but ignore if it is*/
PyErr_Clear();
@@ -5112,23 +5169,23 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
RNA_parameter_list_begin(&parms, &iter);
for (; iter.valid; RNA_parameter_list_next(&iter)) {
parm = iter.parm;
- if (strcmp(arg_name, RNA_property_identifier(parm)) == 0) {
- found = TRUE;
+ if (STREQ(arg_name, RNA_property_identifier(parm))) {
+ found = true;
break;
}
}
RNA_parameter_list_end(&iter);
- if (found == FALSE) {
+ if (found == false) {
BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name);
- first = FALSE;
+ first = false;
}
}
}
/* list good args */
- first = TRUE;
+ first = true;
RNA_parameter_list_begin(&parms, &iter);
for (; iter.valid; RNA_parameter_list_next(&iter)) {
@@ -5137,7 +5194,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
continue;
BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm));
- first = FALSE;
+ first = false;
}
RNA_parameter_list_end(&iter);
@@ -5167,7 +5224,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
BKE_reports_init(&reports, RPT_STORE);
RNA_function_call(C, &reports, self_ptr, self_func, &parms);
- err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE));
+ err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
/* return value */
if (err != -1) {
@@ -5230,7 +5287,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure)
PyObject *ret;
char *args;
- args = RNA_function_as_string_keywords(NULL, self->func, NULL, TRUE, TRUE);
+ args = RNA_function_as_string_keywords(NULL, self->func, NULL, true, true);
ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s",
RNA_struct_identifier(self->ptr.type),
@@ -5962,7 +6019,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self)
{
- if (self->iter.valid == FALSE) {
+ if (self->iter.valid == false) {
PyErr_SetString(PyExc_StopIteration, "pyrna_prop_collection_iter stop");
return NULL;
}
@@ -6029,6 +6086,27 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item);
Py_DECREF(item);
+ /* add staticmethods and classmethods */
+ {
+ const PointerRNA func_ptr = {{NULL}, srna, NULL};
+ const ListBase *lb;
+ Link *link;
+
+ lb = RNA_struct_type_functions(srna);
+ for (link = lb->first; link; link = link->next) {
+ FunctionRNA *func = (FunctionRNA *)link;
+ const int flag = RNA_function_flag(func);
+ if ((flag & FUNC_NO_SELF) && /* is staticmethod or classmethod */
+ (flag & FUNC_REGISTER) == false) /* is not for registration */
+ {
+ /* we may want to set the type of this later */
+ PyObject *func_py = pyrna_func_to_py(&func_ptr, func);
+ PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py);
+ Py_DECREF(func_py);
+ }
+ }
+ }
+
/* done with rna instance */
}
@@ -6068,7 +6146,7 @@ static PyObject *pyrna_srna_ExternalType(StructRNA *srna)
PyObject *newclass;
if (bpy_types_dict == NULL) {
- PyObject *bpy_types = PyImport_ImportModuleLevel((char *)"bpy_types", NULL, NULL, NULL, 0);
+ PyObject *bpy_types = PyImport_ImportModuleLevel("bpy_types", NULL, NULL, NULL, 0);
if (bpy_types == NULL) {
PyErr_Print();
@@ -6229,7 +6307,7 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
pyrna->ptr = *ptr;
#ifdef PYRNA_FREE_SUPPORT
- pyrna->freeptr = FALSE;
+ pyrna->freeptr = false;
#endif
#ifdef USE_PYRNA_STRUCT_REFERENCE
@@ -6309,15 +6387,15 @@ PyObject *pyrna_id_CreatePyObject(ID *id)
}
}
-int pyrna_id_FromPyObject(PyObject *obj, ID **id)
+bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
{
if (BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type))) {
*id = ((BPy_StructRNA *)obj)->ptr.id.data;
- return TRUE;
+ return true;
}
else {
*id = NULL;
- return FALSE;
+ return false;
}
}
@@ -6502,6 +6580,9 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
static PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE;
+/**
+ * Accessed from Python as 'bpy.types'
+ */
PyObject *BPY_rna_types(void)
{
BPy_BaseTypeRNA *self;
@@ -6528,7 +6609,7 @@ PyObject *BPY_rna_types(void)
return (PyObject *)self;
}
-StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix)
+StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix)
{
BPy_StructRNA *py_srna = NULL;
StructRNA *srna;
@@ -6602,7 +6683,7 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyErr_Clear();
- srna = pyrna_struct_as_srna(self, 0, error_prefix);
+ srna = pyrna_struct_as_srna(self, false, error_prefix);
if (!PyErr_Occurred()) {
PyErr_Restore(error_type, error_value, error_traceback);
@@ -6742,14 +6823,14 @@ static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject
return pyrna_deferred_register_props(srna, py_class->tp_dict); /* getattr(..., "__dict__") returns a proxy */
}
-int pyrna_deferred_register_class(StructRNA *srna, PyObject *py_class)
+int pyrna_deferred_register_class(StructRNA *srna, PyTypeObject *py_class)
{
/* Panels and Menus don't need this
* save some time and skip the checks here */
if (!RNA_struct_idprops_register_check(srna))
return 0;
- return pyrna_deferred_register_class_recursive(srna, (PyTypeObject *)py_class);
+ return pyrna_deferred_register_class_recursive(srna, py_class);
}
/*-------------------- Type Registration ------------------------*/
@@ -6759,7 +6840,9 @@ static int rna_function_arg_count(FunctionRNA *func)
const ListBase *lb = RNA_function_defined_parameters(func);
PropertyRNA *parm;
Link *link;
- int count = (RNA_function_flag(func) & FUNC_NO_SELF) ? 0 : 1;
+ int flag = RNA_function_flag(func);
+ int is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
+ int count = is_staticmethod ? 0 : 1;
for (link = lb->first; link; link = link->next) {
parm = (PropertyRNA *)link;
@@ -6781,7 +6864,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
PyObject *py_class = (PyObject *)py_data;
PyObject *base_class = RNA_struct_py_type_get(srna);
PyObject *item;
- int i, flag, arg_count, func_arg_count;
+ int i, flag, is_staticmethod, arg_count, func_arg_count;
const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; /* __name__ */
if (srna_base) {
@@ -6804,6 +6887,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
for (link = lb->first; link; link = link->next) {
func = (FunctionRNA *)link;
flag = RNA_function_flag(func);
+ is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
if (!(flag & FUNC_REGISTER))
continue;
@@ -6814,7 +6898,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
i++;
if (item == NULL) {
- if ((flag & FUNC_REGISTER_OPTIONAL) == 0) {
+ if ((flag & (FUNC_REGISTER_OPTIONAL & ~FUNC_REGISTER)) == 0) {
PyErr_Format(PyExc_AttributeError,
"expected %.200s, %.200s class to have an \"%.200s\" attribute",
class_type, py_class_name,
@@ -6826,7 +6910,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
}
else {
Py_DECREF(item); /* no need to keep a ref, the class owns it (technically we should keep a ref but...) */
- if (flag & FUNC_NO_SELF) {
+ if (is_staticmethod) {
if (PyMethod_Check(item) == 0) {
PyErr_Format(PyExc_TypeError,
"expected %.200s, %.200s class \"%.200s\" attribute to be a method, not a %.200s",
@@ -6850,9 +6934,9 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount;
/* note, the number of args we check for and the number of args we give to
- * @classmethods are different (quirk of python),
+ * @staticmethods are different (quirk of python),
* this is why rna_function_arg_count() doesn't return the value -1*/
- if (flag & FUNC_NO_SELF)
+ if (is_staticmethod)
func_arg_count++;
if (arg_count != func_arg_count) {
@@ -6883,7 +6967,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
/* Sneaky workaround to use the class name as the bl_idname */
#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
- (strcmp(identifier, rna_attr) == 0) { \
+ (STREQ(identifier, rna_attr)) { \
item = PyObject_GetAttr(py_class, py_attr); \
if (item && item != Py_None) { \
if (pyrna_py_to_prop(dummyptr, prop, NULL, \
@@ -6894,7 +6978,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
} \
} \
Py_XDECREF(item); \
- } /* intendionally allow else here */
+ } /* intentionally allow else here */
if BPY_REPLACEMENT_STRING("bl_idname", bpy_intern_str___name__)
else if BPY_REPLACEMENT_STRING("bl_description", bpy_intern_str___doc__)
@@ -6937,8 +7021,10 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
PropertyRNA *parm;
ParameterIterator iter;
PointerRNA funcptr;
- int err = 0, i, flag, ret_len = 0;
- const char is_static = (RNA_function_flag(func) & FUNC_NO_SELF) != 0;
+ int err = 0, i, ret_len = 0;
+ int flag = RNA_function_flag(func);
+ const char is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
+ const char is_classmethod = (flag & FUNC_NO_SELF) && (flag & FUNC_USE_SELF_TYPE);
/* annoying!, need to check if the screen gets set to NULL which is a
* hint that the file was actually re-loaded. */
@@ -6973,7 +7059,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
bpy_context_set(C, &gilstate);
- if (!is_static) {
+ if (!(is_staticmethod || is_classmethod)) {
/* some datatypes (operator, render engine) can store PyObjects for re-use */
if (ptr->data) {
void **instance = RNA_struct_instance(ptr);
@@ -7013,7 +7099,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if (py_class->tp_init) {
#ifdef USE_PEDANTIC_WRITE
const int prev_write = rna_disallow_writes;
- rna_disallow_writes = is_operator ? FALSE : TRUE; /* only operators can write on __init__ */
+ rna_disallow_writes = is_operator ? false : true; /* only operators can write on __init__ */
#endif
/* true in most cases even when the class its self doesn't define an __init__ function. */
@@ -7032,7 +7118,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
#else
const int prev_write = rna_disallow_writes;
- rna_disallow_writes = TRUE;
+ rna_disallow_writes = true;
/* 'almost' all the time calling the class isn't needed.
* We could just do... */
@@ -7064,18 +7150,21 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
}
}
- if (err != -1 && (is_static || py_class_instance)) { /* Initializing the class worked, now run its invoke function */
+ if (err != -1 && (is_staticmethod || is_classmethod || py_class_instance)) { /* Initializing the class worked, now run its invoke function */
PyObject *item = PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func));
-// flag = RNA_function_flag(func);
if (item) {
RNA_pointer_create(NULL, &RNA_Function, func, &funcptr);
args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */
- if (is_static) {
+ if (is_staticmethod) {
i = 0;
}
+ else if (is_classmethod) {
+ PyTuple_SET_ITEM(args, 0, (PyObject *)py_class);
+ i = 1;
+ }
else {
PyTuple_SET_ITEM(args, 0, py_class_instance);
i = 1;
@@ -7105,7 +7194,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
}
#ifdef USE_PEDANTIC_WRITE
- rna_disallow_writes = is_readonly ? TRUE : FALSE;
+ rna_disallow_writes = is_readonly ? true : false;
#endif
/* *** Main Caller *** */
@@ -7114,7 +7203,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
/* *** Done Calling *** */
#ifdef USE_PEDANTIC_WRITE
- rna_disallow_writes = FALSE;
+ rna_disallow_writes = false;
#endif
RNA_parameter_list_end(&iter);
@@ -7209,7 +7298,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if (err != 0) {
ReportList *reports;
/* alert the user, else they wont know unless they see the console. */
- if ((!is_static) &&
+ if ((!is_staticmethod) && (!is_classmethod) &&
(ptr->data) &&
(RNA_struct_is_a(ptr->type, &RNA_Operator)) &&
(is_valid_wm == (CTX_wm_manager(C) != NULL)))
@@ -7332,8 +7421,9 @@ PyDoc_STRVAR(pyrna_register_class_doc,
".. method:: register_class(cls)\n"
"\n"
" Register a subclass of a blender type in (:class:`bpy.types.Panel`,\n"
-" :class:`bpy.types.Menu`, :class:`bpy.types.Header`, :class:`bpy.types.Operator`,\n"
-" :class:`bpy.types.KeyingSetInfo`, :class:`bpy.types.RenderEngine`).\n"
+" :class:`bpy.types.UIList`, :class:`bpy.types.Menu`, :class:`bpy.types.Header`,\n"
+" :class:`bpy.types.Operator`, :class:`bpy.types.KeyingSetInfo`,\n"
+" :class:`bpy.types.RenderEngine`).\n"
"\n"
" If the class has a *register* class method it will be called\n"
" before registration.\n"
@@ -7378,7 +7468,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
}
/* warning: gets parent classes srna, only for the register function */
- srna = pyrna_struct_as_srna(py_class, 1, "register_class(...):");
+ srna = pyrna_struct_as_srna(py_class, true, "register_class(...):");
if (srna == NULL)
return NULL;
@@ -7414,7 +7504,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
srna_new = reg(CTX_data_main(C), &reports, py_class, identifier,
bpy_class_validate, bpy_class_call, bpy_class_free);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
/* python errors validating are not converted into reports so the check above will fail.
@@ -7434,7 +7524,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
*
* item = PyObject_GetAttrString(py_class, "__dict__");
*/
- if (pyrna_deferred_register_class(srna_new, py_class) != 0)
+ if (pyrna_deferred_register_class(srna_new, (PyTypeObject *)py_class) != 0)
return NULL;
/* call classed register method () */
@@ -7521,7 +7611,7 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
return NULL;
}
- srna = pyrna_struct_as_srna(py_class, 0, "unregister_class(...):");
+ srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):");
if (srna == NULL)
return NULL;
@@ -7592,3 +7682,39 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
Py_RETURN_NONE;
}
+
+/* currently this is fairly limited, we would need to make some way to split up
+ * pyrna_callback_classmethod_... if we want more then one callback per type */
+typedef struct BPyRNA_CallBack {
+ PyMethodDef py_method;
+ StructRNA *bpy_srna;
+} PyRNA_CallBack;
+
+static struct BPyRNA_CallBack pyrna_cb_methods[] = {
+ {{"draw_handler_add", (PyCFunction)pyrna_callback_classmethod_add, METH_VARARGS | METH_STATIC, ""}, &RNA_Space},
+ {{"draw_handler_remove", (PyCFunction)pyrna_callback_classmethod_remove, METH_VARARGS | METH_STATIC, ""}, &RNA_Space},
+ {{NULL, NULL, 0, NULL}, NULL}
+};
+
+void BPY_rna_register_cb(void)
+{
+ int i;
+
+ for (i = 0; pyrna_cb_methods[i].bpy_srna; i++) {
+ PyObject *cls;
+ PyObject *func;
+ PyObject *classmethod;
+ PyObject *args = PyTuple_New(1);
+
+ cls = pyrna_srna_Subtype(pyrna_cb_methods[i].bpy_srna);
+ func = PyCFunction_New(&pyrna_cb_methods[i].py_method, NULL);
+ PyTuple_SET_ITEM(args, 0, func);
+ classmethod = PyObject_CallObject((PyObject *)&PyClassMethod_Type, args);
+
+ PyObject_SetAttrString(cls, pyrna_cb_methods[i].py_method.ml_name, classmethod);
+
+ Py_DECREF(classmethod);
+ Py_DECREF(args); /* clears 'func' too */
+ Py_DECREF(cls);
+ }
+}