Merged changes in the trunk up to revision 41638.
Conflicts resolved: doc/python_api/sphinx_doc_gen.py source/blender/blenkernel/BKE_main.h source/blender/blenkernel/intern/library.c source/blender/blenloader/intern/readfile.c source/blender/blenloader/intern/writefile.c source/blender/editors/include/UI_resources.h source/blender/editors/interface/resources.c source/blender/makesdna/DNA_ID.h source/blender/makesdna/intern/makesdna.c source/blender/makesrna/intern/rna_internal.h source/blender/makesrna/intern/rna_main.c source/blender/makesrna/intern/rna_main_api.c source/blender/makesrna/intern/rna_scene.c
This commit is contained in:
@@ -22,11 +22,11 @@
|
||||
|
||||
/** \file blender/python/intern/bpy.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file defines the '_bpy' module which is used by python's 'bpy' package
|
||||
* to access C defined builtin functions.
|
||||
* A script writer should never directly access this module.
|
||||
*/
|
||||
|
||||
|
||||
/* This file defines the '_bpy' module which is used by python's 'bpy' package.
|
||||
* a script writer should never directly access this module */
|
||||
|
||||
#define WITH_PYTHON /* for AUD_PyInit.h, possibly others */
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_app.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file defines a 'PyStructSequence' accessed via 'bpy.app', mostly
|
||||
* exposing static applications variables such as version and buildinfo
|
||||
* however some writable variables have been added such as 'debug' and 'tempdir'
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_app_handlers.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file defines a 'PyStructSequence' accessed via 'bpy.app.handlers',
|
||||
* which exposes various lists that the script author can add callback
|
||||
* functions into (called via blenders generic BLI_cb api)
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
@@ -38,15 +42,22 @@ void bpy_app_generic_callback(struct Main *main, struct ID *id, void *arg);
|
||||
static PyTypeObject BlenderAppCbType;
|
||||
|
||||
static PyStructSequence_Field app_cb_info_fields[]= {
|
||||
{(char *)"frame_change_pre", NULL},
|
||||
{(char *)"frame_change_post", NULL},
|
||||
{(char *)"render_pre", NULL},
|
||||
{(char *)"render_post", NULL},
|
||||
{(char *)"render_stats", NULL},
|
||||
{(char *)"load_pre", NULL},
|
||||
{(char *)"load_post", NULL},
|
||||
{(char *)"save_pre", NULL},
|
||||
{(char *)"save_post", NULL},
|
||||
{(char *)"frame_change_pre", (char *)"Callback list - on frame change for playback and rendering (before)"},
|
||||
{(char *)"frame_change_post", (char *)"Callback list - on frame change for playback and rendering (after)"},
|
||||
{(char *)"render_pre", (char *)"Callback list - on render (before)"},
|
||||
{(char *)"render_post", (char *)"Callback list - on render (after)"},
|
||||
{(char *)"render_stats", (char *)"Callback list - on printing render statistics"},
|
||||
{(char *)"load_pre", (char *)"Callback list - on loading a new blend file (before)"},
|
||||
{(char *)"load_post", (char *)"Callback list - on loading a new blend file (after)"},
|
||||
{(char *)"save_pre", (char *)"Callback list - on saving a blend file (before)"},
|
||||
{(char *)"save_post", (char *)"Callback list - on saving a blend file (after)"},
|
||||
{(char *)"scene_update_pre", (char *)"Callback list - on updating the scenes data (before)"},
|
||||
{(char *)"scene_update_post", (char *)"Callback list - on updating the scenes data (after)"},
|
||||
|
||||
/* sets the permanent tag */
|
||||
# define APP_CB_OTHER_FIELDS 1
|
||||
{(char *)"persistent", (char *)"Function decorator for callback functions not to be removed when loading new files"},
|
||||
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -63,6 +74,95 @@ static PyStructSequence_Desc app_cb_info_desc= {
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* --------------------------------------------------------------------------*/
|
||||
/* permanent tagging code */
|
||||
#define PERMINENT_CB_ID "_bpy_persistent"
|
||||
|
||||
static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *UNUSED(kwds))
|
||||
{
|
||||
PyObject *value;
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value))
|
||||
return NULL;
|
||||
|
||||
if (PyFunction_Check(value)) {
|
||||
PyObject **dict_ptr= _PyObject_GetDictPtr(value);
|
||||
if (dict_ptr == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"bpy.app.handlers.persistent wasn't able to "
|
||||
"get the dictionary from the function passed");
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
/* set id */
|
||||
if (*dict_ptr == NULL) {
|
||||
*dict_ptr= PyDict_New();
|
||||
}
|
||||
|
||||
PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None);
|
||||
}
|
||||
|
||||
Py_INCREF(value);
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"bpy.app.handlers.persistent expected a function");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* dummy type because decorators can't be PyCFunctions */
|
||||
static PyTypeObject BPyPersistent_Type = {
|
||||
|
||||
#if defined(_MSC_VER) || defined(FREE_WINDOWS)
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
#else
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
#endif
|
||||
|
||||
"persistent", /* tp_name */
|
||||
0, /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
0, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_reserved */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
||||
Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
bpy_app_handlers_persistent_new, /* tp_new */
|
||||
0, /* tp_free */
|
||||
};
|
||||
|
||||
static PyObject *py_cb_array[BLI_CB_EVT_TOT]= {NULL};
|
||||
|
||||
static PyObject *make_app_cb_info(void)
|
||||
@@ -81,10 +181,13 @@ static PyObject *make_app_cb_info(void)
|
||||
}
|
||||
PyStructSequence_SET_ITEM(app_cb_info, pos, (py_cb_array[pos]= PyList_New(0)));
|
||||
}
|
||||
if (app_cb_info_fields[pos].name != NULL) {
|
||||
if (app_cb_info_fields[pos + APP_CB_OTHER_FIELDS].name != NULL) {
|
||||
Py_FatalError("invalid callback slots 2");
|
||||
}
|
||||
|
||||
/* custom function */
|
||||
PyStructSequence_SET_ITEM(app_cb_info, pos++, (PyObject *)&BPyPersistent_Type);
|
||||
|
||||
return app_cb_info;
|
||||
}
|
||||
|
||||
@@ -92,6 +195,14 @@ PyObject *BPY_app_handlers_struct(void)
|
||||
{
|
||||
PyObject *ret;
|
||||
|
||||
#if defined(_MSC_VER) || defined(FREE_WINDOWS)
|
||||
BPyPersistent_Type.ob_base.ob_base.ob_type= &PyType_Type;
|
||||
#endif
|
||||
|
||||
if (PyType_Ready(&BPyPersistent_Type) < 0) {
|
||||
BLI_assert(!"error initializing 'bpy.app.handlers.persistent'");
|
||||
}
|
||||
|
||||
PyStructSequence_InitType(&BlenderAppCbType, &app_cb_info_desc);
|
||||
|
||||
ret= make_app_cb_info();
|
||||
@@ -118,12 +229,46 @@ PyObject *BPY_app_handlers_struct(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void BPY_app_handlers_reset(void)
|
||||
void BPY_app_handlers_reset(const short do_all)
|
||||
{
|
||||
int pos= 0;
|
||||
|
||||
if (do_all) {
|
||||
for (pos= 0; pos < BLI_CB_EVT_TOT; pos++) {
|
||||
PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL);
|
||||
/* clear list */
|
||||
PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* save string conversion thrashing */
|
||||
PyObject *perm_id_str= PyUnicode_FromString(PERMINENT_CB_ID);
|
||||
|
||||
for (pos= 0; pos < BLI_CB_EVT_TOT; pos++) {
|
||||
/* clear only items without PERMINENT_CB_ID */
|
||||
PyObject *ls= py_cb_array[pos];
|
||||
Py_ssize_t i;
|
||||
|
||||
PyObject *item;
|
||||
PyObject **dict_ptr;
|
||||
|
||||
for(i= PyList_GET_SIZE(ls) - 1; i >= 0; i--) {
|
||||
|
||||
if ( (PyFunction_Check((item= PyList_GET_ITEM(ls, i)))) &&
|
||||
(dict_ptr= _PyObject_GetDictPtr(item)) &&
|
||||
(*dict_ptr) &&
|
||||
(PyDict_GetItem(*dict_ptr, perm_id_str) != NULL))
|
||||
{
|
||||
/* keep */
|
||||
}
|
||||
else {
|
||||
/* remove */
|
||||
/* PySequence_DelItem(ls, i); */ /* more obvious buw slower */
|
||||
PyList_SetSlice(ls, i, i + 1, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(perm_id_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_driver.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file defines the 'BPY_driver_exec' to execute python driver expressions,
|
||||
* called by the animation system, there are also some utility functions
|
||||
* to deal with the namespace used for driver execution.
|
||||
*/
|
||||
|
||||
/* ****************************************** */
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_interface.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file deals with embedding the python interpreter within blender,
|
||||
* starting and stopping python and exposing blender/python modules so they can
|
||||
* be accesses from scripts.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_interface_atexit.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file inserts an exit callback into pythons 'atexit' module.
|
||||
* Without this sys.exit() can crash because blender is not properly closing
|
||||
* resources.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_intern_string.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* Store python versions of strings frequently used for python lookups
|
||||
* to avoid converting, creating the hash and freeing every time as
|
||||
* PyDict_GetItemString and PyObject_GetAttrString do.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_library.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file exposed blend file library appending/linking to python, typically
|
||||
* this would be done via RNA api but in this case a hand written python api
|
||||
* allows us to use pythons context manager (__enter__ and __exit__).
|
||||
*
|
||||
* Everything here is exposed via bpy.data.libraries.load(...) which returns
|
||||
* a context manager.
|
||||
*/
|
||||
|
||||
/* nifty feature. swap out strings for RNA data */
|
||||
@@ -71,8 +78,8 @@ static PyObject *bpy_lib_dir(BPy_Library *self);
|
||||
|
||||
static PyMethodDef bpy_lib_methods[]= {
|
||||
{"__enter__", (PyCFunction)bpy_lib_enter, METH_NOARGS},
|
||||
{"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS},
|
||||
{"__dir__", (PyCFunction)bpy_lib_dir, METH_NOARGS},
|
||||
{"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS},
|
||||
{"__dir__", (PyCFunction)bpy_lib_dir, METH_NOARGS},
|
||||
{NULL} /* sentinel */
|
||||
};
|
||||
|
||||
@@ -283,7 +290,7 @@ static void bpy_lib_exit_warn_idname(BPy_Library *self, const char *name_plural,
|
||||
PyObject *exc, *val, *tb;
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
if (PyErr_WarnFormat(PyExc_UserWarning, 1,
|
||||
"load: '%s' does not contain %s[\"%s\"]",
|
||||
"load: '%s' does not contain %s[\"%s\"]",
|
||||
self->abspath, name_plural, idname)) {
|
||||
/* Spurious errors can appear at shutdown */
|
||||
if (PyErr_ExceptionMatches(PyExc_Warning)) {
|
||||
@@ -298,7 +305,7 @@ static void bpy_lib_exit_warn_type(BPy_Library *self, PyObject *item)
|
||||
PyObject *exc, *val, *tb;
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
if (PyErr_WarnFormat(PyExc_UserWarning, 1,
|
||||
"load: '%s' expected a string type, not a %.200s",
|
||||
"load: '%s' expected a string type, not a %.200s",
|
||||
self->abspath, Py_TYPE(item)->tp_name)) {
|
||||
/* Spurious errors can appear at shutdown */
|
||||
if (PyErr_ExceptionMatches(PyExc_Warning)) {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -24,6 +22,13 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_operator.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file defines '_bpy.ops', an internal python module which gives python
|
||||
* the ability to inspect and call both C and Python defined operators.
|
||||
*
|
||||
* \note
|
||||
* This module is exposed to the user via 'release/scripts/modules/bpy/ops.py'
|
||||
* which fakes exposing operators as modules/functions using its own classes.
|
||||
*/
|
||||
|
||||
|
||||
@@ -380,7 +385,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
PointerRNA ptr;
|
||||
char *opname= _PyUnicode_AsString(value);
|
||||
const char *opname= _PyUnicode_AsString(value);
|
||||
BPy_StructRNA *pyrna= NULL;
|
||||
|
||||
if (opname==NULL) {
|
||||
@@ -413,7 +418,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
|
||||
wmOperatorType *ot;
|
||||
wmOperator *op;
|
||||
PointerRNA ptr;
|
||||
char *opname= _PyUnicode_AsString(value);
|
||||
const char *opname= _PyUnicode_AsString(value);
|
||||
BPy_StructRNA *pyrna= NULL;
|
||||
|
||||
if (opname==NULL) {
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_operator_wrap.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file is so python can define operators that C can call into.
|
||||
* The generic callback functions for python operators are defines in
|
||||
* 'rna_wm.c', some calling into functions here to do python specific
|
||||
* functionality.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_props.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file defines 'bpy.props' module used so scripts can define their own
|
||||
* rna properties for use with python operators or adding new properties to
|
||||
* existing blender types.
|
||||
*/
|
||||
|
||||
|
||||
@@ -254,7 +258,7 @@ static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_c
|
||||
{
|
||||
/* assume this is already checked for type and arg length */
|
||||
if (update_cb) {
|
||||
PyObject **py_data= MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, "bpy_prop_callback_assign");
|
||||
PyObject **py_data= MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
|
||||
RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb);
|
||||
py_data[BPY_DATA_CB_SLOT_UPDATE]= update_cb;
|
||||
RNA_def_py_data(prop, py_data);
|
||||
@@ -279,52 +283,60 @@ static int py_long_as_int(PyObject *py_long, int *r_int)
|
||||
|
||||
/* this define runs at the start of each function and deals with
|
||||
* returning a deferred property (to be registered later) */
|
||||
#define BPY_PROPDEF_HEAD(_func) \
|
||||
if (PyTuple_GET_SIZE(args) == 1) { \
|
||||
PyObject *ret; \
|
||||
self= PyTuple_GET_ITEM(args, 0); \
|
||||
args= PyTuple_New(0); \
|
||||
ret= BPy_##_func(self, args, kw); \
|
||||
Py_DECREF(args); \
|
||||
return ret; \
|
||||
} \
|
||||
else if (PyTuple_GET_SIZE(args) > 1) { \
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \
|
||||
return NULL; \
|
||||
} \
|
||||
srna= srna_from_self(self, #_func"(...):"); \
|
||||
if (srna==NULL) { \
|
||||
if (PyErr_Occurred()) \
|
||||
return NULL; \
|
||||
return bpy_prop_deferred_return((void *)pymeth_##_func, kw); \
|
||||
} \
|
||||
#define BPY_PROPDEF_HEAD(_func) \
|
||||
if (PyTuple_GET_SIZE(args) == 1) { \
|
||||
PyObject *ret; \
|
||||
self= PyTuple_GET_ITEM(args, 0); \
|
||||
args= PyTuple_New(0); \
|
||||
ret= BPy_##_func(self, args, kw); \
|
||||
Py_DECREF(args); \
|
||||
return ret; \
|
||||
} \
|
||||
else if (PyTuple_GET_SIZE(args) > 1) { \
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \
|
||||
return NULL; \
|
||||
} \
|
||||
srna= srna_from_self(self, #_func"(...):"); \
|
||||
if (srna==NULL) { \
|
||||
if (PyErr_Occurred()) \
|
||||
return NULL; \
|
||||
return bpy_prop_deferred_return((void *)pymeth_##_func, kw); \
|
||||
} \
|
||||
|
||||
/* terse macros for error checks shared between all funcs cant use function
|
||||
* calls because of static strins passed to pyrna_set_to_enum_bitfield */
|
||||
#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \
|
||||
if (id_len >= MAX_IDPROP_NAME) { \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(): '%.200s' too long, max length is %d", \
|
||||
id, MAX_IDPROP_NAME-1); \
|
||||
return NULL; \
|
||||
} \
|
||||
if (RNA_def_property_free_identifier(srna, id) == -1) { \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(): '%s' is defined as a non-dynamic type", \
|
||||
id); \
|
||||
return NULL; \
|
||||
} \
|
||||
if (pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, pyopts, &opts, #_func"(options={...}):")) \
|
||||
return NULL; \
|
||||
#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \
|
||||
if (id_len >= MAX_IDPROP_NAME) { \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(): '%.200s' too long, max length is %d", \
|
||||
id, MAX_IDPROP_NAME-1); \
|
||||
return NULL; \
|
||||
} \
|
||||
if (RNA_def_property_free_identifier(srna, id) == -1) { \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(): '%s' is defined as a non-dynamic type", \
|
||||
id); \
|
||||
return NULL; \
|
||||
} \
|
||||
if (pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \
|
||||
pyopts, \
|
||||
&opts, \
|
||||
#_func"(options={...}):")) \
|
||||
{ \
|
||||
return NULL; \
|
||||
} \
|
||||
|
||||
#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \
|
||||
BPY_PROPDEF_CHECK(_func, _property_flag_items) \
|
||||
if (pysubtype && RNA_enum_value_from_id(_subtype, pysubtype, &subtype)==0) { \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(subtype='%s'): invalid subtype", \
|
||||
pysubtype); \
|
||||
return NULL; \
|
||||
} \
|
||||
#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \
|
||||
BPY_PROPDEF_CHECK(_func, _property_flag_items) \
|
||||
if (pysubtype && RNA_enum_value_from_id(_subtype, \
|
||||
pysubtype, \
|
||||
&subtype)==0) \
|
||||
{ \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(subtype='%s'): invalid subtype", \
|
||||
pysubtype); \
|
||||
return NULL; \
|
||||
} \
|
||||
|
||||
|
||||
#define BPY_PROPDEF_NAME_DOC \
|
||||
@@ -1211,7 +1223,7 @@ static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix
|
||||
if (!srna) {
|
||||
if (PyErr_Occurred()) {
|
||||
PyObject *msg= PyC_ExceptionBuffer();
|
||||
char *msg_char= _PyUnicode_AsString(msg);
|
||||
const char *msg_char= _PyUnicode_AsString(msg);
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%.200s expected an RNA type derived from PropertyGroup, failed with: %s",
|
||||
error_prefix, msg_char);
|
||||
|
||||
@@ -22,9 +22,14 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_rna.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file is the main interface between python and blenders data api (RNA),
|
||||
* exposing RNA to python so blender data can be accessed in a python like way.
|
||||
*
|
||||
* The two main types are 'BPy_StructRNA' and 'BPy_PropertyRNA' - the base
|
||||
* classes for most of the data python accesses in blender.
|
||||
*/
|
||||
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -82,10 +87,10 @@
|
||||
static PyObject* pyrna_struct_Subtype(PointerRNA *ptr);
|
||||
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
|
||||
|
||||
#define BPY_DOC_ID_PROP_TYPE_NOTE \
|
||||
" .. note::\n" \
|
||||
"\n" \
|
||||
" Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and \n" \
|
||||
#define BPY_DOC_ID_PROP_TYPE_NOTE \
|
||||
" .. note::\n" \
|
||||
"\n" \
|
||||
" Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and \n" \
|
||||
" :class:`bpy.types.PoseBone` classes support custom properties.\n"
|
||||
|
||||
|
||||
@@ -6404,17 +6409,19 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
|
||||
if (item==NULL) {
|
||||
/* Sneaky workaround to use the class name as the bl_idname */
|
||||
|
||||
#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
|
||||
if (strcmp(identifier, rna_attr) == 0) { \
|
||||
item= PyObject_GetAttrString(py_class, py_attr); \
|
||||
if (item && item != Py_None) { \
|
||||
if (pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class:") != 0) { \
|
||||
Py_DECREF(item); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
Py_XDECREF(item); \
|
||||
} \
|
||||
#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
|
||||
if (strcmp(identifier, rna_attr) == 0) { \
|
||||
item= PyObject_GetAttrString(py_class, py_attr); \
|
||||
if (item && item != Py_None) { \
|
||||
if (pyrna_py_to_prop(dummyptr, prop, NULL, \
|
||||
item, "validating class:") != 0) \
|
||||
{ \
|
||||
Py_DECREF(item); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
Py_XDECREF(item); \
|
||||
} \
|
||||
|
||||
|
||||
BPY_REPLACEMENT_STRING("bl_idname", "__name__");
|
||||
@@ -6468,7 +6475,9 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
|
||||
const int is_operator= RNA_struct_is_a(ptr->type, &RNA_Operator);
|
||||
const char *func_id= RNA_function_identifier(func);
|
||||
/* testing, for correctness, not operator and not draw function */
|
||||
const short is_readonly= strstr("draw", func_id) || /*strstr("render", func_id) ||*/ !is_operator;
|
||||
const short is_readonly= ((strncmp("draw", func_id, 4) ==0) || /* draw or draw_header */
|
||||
/*strstr("render", func_id) ||*/
|
||||
!is_operator);
|
||||
#endif
|
||||
|
||||
py_class= RNA_struct_py_type_get(ptr->type);
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_rna_anim.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file defines the animation related methods used in bpy_rna.c
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
@@ -15,13 +15,15 @@
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Arystanbek Dyussenov
|
||||
* Contributor(s): Arystanbek Dyussenov, Campbell Barton
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/python/intern/bpy_rna_array.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file deals with array access for 'BPy_PropertyArrayRNA' from bpy_rna.c
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_rna_callback.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file currently exposes callbacks for interface regions but may be
|
||||
* extended later.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_traceback.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file contains utility functions for getting data from a python stack
|
||||
* trace.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -22,9 +22,11 @@
|
||||
|
||||
/** \file blender/python/intern/bpy_util.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file contains blender/python utility functions for the api's internal
|
||||
* use (unrelated to 'bpy.utils')
|
||||
*/
|
||||
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "bpy_util.h"
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
|
||||
/** \file blender/python/intern/gpu.c
|
||||
* \ingroup pythonintern
|
||||
*
|
||||
* This file defines the 'gpu' module, used to get GLSL shader code and data
|
||||
* from blender materials.
|
||||
*/
|
||||
|
||||
/* python redefines */
|
||||
|
||||
Reference in New Issue
Block a user