Merged changes in the trunk up to revision 34193.

Conflicts resolved:
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/keyframes_draw.c
source/blender/editors/animation/keyframes_edit.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/space_nla/nla_channels.c
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_scene.c

API changes resolved:
source/blender/freestyle/intern/system/PythonInterpreter.h
This commit is contained in:
Tamito Kajiyama
2011-01-09 15:07:14 +00:00
591 changed files with 9099 additions and 5273 deletions

View File

@@ -35,8 +35,9 @@
#include "BLI_path_util.h"
#include "BLI_bpath.h"
#include "BLI_utildefines.h"
#include "BKE_utildefines.h"
#include "BKE_global.h" /* XXX, G.main only */
#include "MEM_guardedalloc.h"

View File

@@ -25,8 +25,9 @@
#include "bpy_app.h"
#include "BLI_path_util.h"
#include "BLI_utildefines.h"
#include "BKE_utildefines.h"
#include "BKE_blender.h"
#include "BKE_global.h"
#include "structseq.h"

View File

@@ -69,41 +69,15 @@ int bpy_pydriver_create_dict(void)
Py_DECREF(mod);
}
#if 0 // non existant yet
mod = PyImport_ImportModule("Blender.Noise");
if (mod) {
PyDict_SetItemString(d, "noise", mod);
PyDict_SetItemString(d, "n", mod);
Py_DECREF(mod);
} else {
PyErr_Clear();
}
/* If there's a Blender text called pydrivers.py, import it.
* Users can add their own functions to this module.
*/
if (G.f & G_SCRIPT_AUTOEXEC) {
mod = importText("pydrivers"); /* can also use PyImport_Import() */
if (mod) {
PyDict_SetItemString(d, "pydrivers", mod);
PyDict_SetItemString(d, "p", mod);
Py_DECREF(mod);
} else {
PyErr_Clear();
}
}
#endif // non existant yet
return 0;
}
/* Update function, it gets rid of pydrivers global dictionary, forcing
* BPY_eval_driver to recreate it. This function is used to force
* BPY_driver_exec to recreate it. This function is used to force
* reloading the Blender text module "pydrivers.py", if available, so
* updates in it reach pydriver evaluation.
*/
void BPY_reset_driver(void)
void BPY_driver_reset(void)
{
PyGILState_STATE gilstate;
int use_gil= 1; // (PyThreadState_Get()==NULL);
@@ -124,7 +98,7 @@ void BPY_reset_driver(void)
}
/* error return function for BPY_eval_pydriver */
static float pydriver_error(ChannelDriver *driver)
static void pydriver_error(ChannelDriver *driver)
{
driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */
fprintf(stderr, "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n", driver->expression);
@@ -132,8 +106,6 @@ static float pydriver_error(ChannelDriver *driver)
// BPy_errors_to_report(NULL); // TODO - reports
PyErr_Print();
PyErr_Clear();
return 0.0f;
}
/* This evals py driver expressions, 'expr' is a Python expression that
@@ -143,7 +115,7 @@ static float pydriver_error(ChannelDriver *driver)
* bake operator which intern starts a thread which calls scene update which
* does a driver update. to avoid a deadlock check PyThreadState_Get() if PyGILState_Ensure() is needed.
*/
float BPY_eval_driver (ChannelDriver *driver)
float BPY_driver_exec(ChannelDriver *driver)
{
PyObject *driver_vars=NULL;
PyObject *retval= NULL;
@@ -232,15 +204,15 @@ float BPY_eval_driver (ChannelDriver *driver)
/* try to add to dictionary */
/* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */
if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg)) { /* use string interning for faster namespace creation */
if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) < 0) { /* use string interning for faster namespace creation */
/* this target failed - bad name */
if (targets_ok) {
/* first one - print some extra info for easier identification */
fprintf(stderr, "\nBPY_eval_driver() - Error while evaluating PyDriver:\n");
fprintf(stderr, "\nBPY_driver_eval() - Error while evaluating PyDriver:\n");
targets_ok= 0;
}
fprintf(stderr, "\tBPY_eval_driver() - couldn't add variable '%s' to namespace\n", dvar->name);
fprintf(stderr, "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n", dvar->name);
// BPy_errors_to_report(NULL); // TODO - reports
PyErr_Print();
PyErr_Clear();
@@ -280,7 +252,7 @@ float BPY_eval_driver (ChannelDriver *driver)
return (float)result;
}
else {
fprintf(stderr, "\tBPY_eval_driver() - driver '%s' evaluates to '%f'\n", dvar->name, result);
fprintf(stderr, "\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n", dvar->name, result);
return 0.0f;
}
}

View File

@@ -30,6 +30,8 @@
#include <Python.h>
#include "MEM_guardedalloc.h"
#include "bpy.h"
#include "bpy_rna.h"
#include "bpy_util.h"
@@ -37,12 +39,12 @@
#include "DNA_space_types.h"
#include "DNA_text_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_path_util.h"
#include "BLI_math_base.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_utildefines.h"
#include "BKE_context.h"
#include "BKE_text.h"
#include "BKE_font.h" /* only for utf8towchar */
@@ -88,7 +90,7 @@ void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
fprintf(stderr, "ERROR: Python context called with a NULL Context. this should not happen!\n");
}
BPY_update_modules(C); /* can give really bad results if this isnt here */
BPY_modules_update(C); /* can give really bad results if this isnt here */
#ifdef TIME_PY_RUN
if(bpy_timer_count==0) {
@@ -128,7 +130,7 @@ void bpy_context_clear(bContext *UNUSED(C), PyGILState_STATE *gilstate)
}
}
void BPY_free_compiled_text( struct Text *text )
void BPY_text_free_code(Text *text)
{
if( text->compiled ) {
Py_DECREF( ( PyObject * ) text->compiled );
@@ -136,7 +138,7 @@ void BPY_free_compiled_text( struct Text *text )
}
}
void BPY_update_modules(bContext *C)
void BPY_modules_update(bContext *C)
{
#if 0 // slow, this runs all the time poll, draw etc 100's of time a sec.
PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
@@ -150,7 +152,7 @@ void BPY_update_modules(bContext *C)
}
/* must be called before Py_Initialize */
void BPY_start_python_path(void)
void BPY_python_start_path(void)
{
char *py_path_bundle= BLI_get_folder(BLENDER_PYTHON, NULL);
@@ -191,7 +193,7 @@ void BPY_start_python_path(void)
void BPY_set_context(bContext *C)
void BPY_context_set(bContext *C)
{
BPy_SetContext(C);
}
@@ -214,8 +216,8 @@ static struct _inittab bpy_internal_modules[]= {
{NULL, NULL}
};
/* call BPY_set_context first */
void BPY_start_python( int argc, char **argv )
/* call BPY_context_set first */
void BPY_python_start( int argc, char **argv )
{
PyThreadState *py_tstate = NULL;
@@ -227,7 +229,7 @@ void BPY_start_python( int argc, char **argv )
/* builtin modules */
PyImport_ExtendInittab(bpy_internal_modules);
BPY_start_python_path(); /* allow to use our own included python */
BPY_python_start_path(); /* allow to use our own included python */
Py_Initialize( );
@@ -278,7 +280,7 @@ void BPY_start_python( int argc, char **argv )
PyEval_ReleaseThread(py_tstate);
}
void BPY_end_python( void )
void BPY_python_end(void)
{
// fprintf(stderr, "Ending Python!\n");
@@ -312,12 +314,13 @@ void BPY_end_python( void )
}
/* Can run a file or text block */
int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
{
PyObject *py_dict= NULL, *py_result= NULL;
PyGILState_STATE gilstate;
BKE_assert(fn || text);
if (fn==NULL && text==NULL) {
return 0;
}
@@ -327,7 +330,7 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
if (text) {
char fn_dummy[FILE_MAXDIR];
bpy_text_filename_get(fn_dummy, text);
if( !text->compiled ) { /* if it wasn't already compiled, do it now */
char *buf = txt_to_buf( text );
@@ -336,8 +339,8 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
MEM_freeN( buf );
if( PyErr_Occurred( ) ) {
BPY_free_compiled_text( text );
if(PyErr_Occurred()) {
BPY_text_free_code(text);
}
}
@@ -345,7 +348,7 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
py_dict = PyC_DefaultNameSpace(fn_dummy);
py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict);
}
}
else {
FILE *fp= fopen(fn, "r");
@@ -354,9 +357,9 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
py_dict = PyC_DefaultNameSpace(fn);
#ifdef _WIN32
/* Previously we used PyRun_File to run directly the code on a FILE
/* Previously we used PyRun_File to run directly the code on a FILE
* object, but as written in the Python/C API Ref Manual, chapter 2,
* 'FILE structs for different C libraries can be different and
* 'FILE structs for different C libraries can be different and
* incompatible'.
* So now we load the script file data to a buffer */
{
@@ -380,14 +383,14 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
py_result= NULL;
}
}
if (!py_result) {
BPy_errors_to_report(reports);
} else {
Py_DECREF( py_result );
}
/* super annoying, undo _PyModule_Clear() */
/* super annoying, undo _PyModule_Clear() */
#define PYMODULE_CLEAR_WORKAROUND
if(py_dict) {
@@ -405,92 +408,22 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
#endif
#undef PYMODULE_CLEAR_WORKAROUND
}
bpy_context_clear(C, &gilstate);
return py_result ? 1:0;
return (py_result != NULL);
}
/* Can run a file or text block */
int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports)
{
return python_script_exec(C, filepath, NULL, reports);
}
/* TODO - move into bpy_space.c ? */
/* GUI interface routines */
/* Copied from Draw.c */
static void exit_pydraw( SpaceScript * sc, short err )
int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports)
{
Script *script = NULL;
if( !sc || !sc->script )
return;
script = sc->script;
if( err ) {
BPy_errors_to_report(NULL); // TODO, reports
script->flags = 0; /* mark script struct for deletion */
SCRIPT_SET_NULL(script);
script->scriptname[0] = '\0';
script->scriptarg[0] = '\0';
// XXX 2.5 error_pyscript();
// XXX 2.5 scrarea_queue_redraw( sc->area );
}
#if 0 // XXX 2.5
BPy_Set_DrawButtonsList(sc->but_refs);
BPy_Free_DrawButtonsList(); /*clear all temp button references*/
#endif
sc->but_refs = NULL;
Py_XDECREF( ( PyObject * ) script->py_draw );
Py_XDECREF( ( PyObject * ) script->py_event );
Py_XDECREF( ( PyObject * ) script->py_button );
script->py_draw = script->py_event = script->py_button = NULL;
}
static int bpy_run_script_init(bContext *C, SpaceScript * sc)
{
if (sc->script==NULL)
return 0;
if (sc->script->py_draw==NULL && sc->script->scriptname[0] != '\0')
BPY_run_python_script(C, sc->script->scriptname, NULL, NULL);
if (sc->script->py_draw==NULL)
return 0;
return 1;
}
int BPY_run_script_space_draw(const struct bContext *C, SpaceScript * sc)
{
if (bpy_run_script_init( (bContext *)C, sc)) {
PyGILState_STATE gilstate = PyGILState_Ensure();
PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
if (result==NULL)
exit_pydraw(sc, 1);
PyGILState_Release(gilstate);
}
return 1;
}
// XXX - not used yet, listeners dont get a context
int BPY_run_script_space_listener(bContext *C, SpaceScript * sc)
{
if (bpy_run_script_init(C, sc)) {
PyGILState_STATE gilstate = PyGILState_Ensure();
PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
if (result==NULL)
exit_pydraw(sc, 1);
PyGILState_Release(gilstate);
}
return 1;
return python_script_exec(C, NULL, text, reports);
}
void BPY_DECREF(void *pyob_ptr)
@@ -500,57 +433,7 @@ void BPY_DECREF(void *pyob_ptr)
PyGILState_Release(gilstate);
}
#if 0
/* called from the the scripts window, assume context is ok */
int BPY_run_python_script_space(const char *modulename, const char *func)
{
PyObject *py_dict, *py_result= NULL;
char pystring[512];
PyGILState_STATE gilstate;
/* for calling the module function */
PyObject *py_func,
gilstate = PyGILState_Ensure();
py_dict = PyC_DefaultNameSpace("<dummy>");
PyObject *module = PyImport_ImportModule(scpt->script.filename);
if (module==NULL) {
PyErr_SetFormat(PyExc_SystemError, "could not import '%s'", scpt->script.filename);
}
else {
py_func = PyObject_GetAttrString(modulename, func);
if (py_func==NULL) {
PyErr_SetFormat(PyExc_SystemError, "module has no function '%s.%s'\n", scpt->script.filename, func);
}
else {
Py_DECREF(py_func);
if (!PyCallable_Check(py_func)) {
PyErr_SetFormat(PyExc_SystemError, "module item is not callable '%s.%s'\n", scpt->script.filename, func);
}
else {
py_result= PyObject_CallObject(py_func, NULL); // XXX will need args eventually
}
}
}
if (!py_result) {
BPy_errors_to_report(NULL); // TODO - reports
} else
Py_DECREF( py_result );
Py_XDECREF(module);
PyDict_SetItemString(PyThreadState_GET()->interp->modules, "__main__", Py_None);
PyGILState_Release(gilstate);
return 1;
}
#endif
int BPY_eval_button(bContext *C, const char *expr, double *value)
int BPY_button_exec(bContext *C, const char *expr, double *value)
{
PyGILState_STATE gilstate;
PyObject *py_dict, *mod, *retval;
@@ -622,7 +505,7 @@ int BPY_eval_button(bContext *C, const char *expr, double *value)
return error_ret;
}
int BPY_eval_string(bContext *C, const char *expr)
int BPY_string_exec(bContext *C, const char *expr)
{
PyGILState_STATE gilstate;
PyObject *py_dict, *retval;
@@ -657,7 +540,7 @@ int BPY_eval_string(bContext *C, const char *expr)
}
void BPY_load_user_modules(bContext *C)
void BPY_modules_load_user(bContext *C)
{
PyGILState_STATE gilstate;
Main *bmain= CTX_data_main(C);
@@ -690,7 +573,7 @@ void BPY_load_user_modules(bContext *C)
bpy_context_clear(C, &gilstate);
}
int BPY_context_get(bContext *C, const char *member, bContextDataResult *result)
int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
{
PyObject *pyctx= (PyObject *)CTX_py_dict_get(C);
PyObject *item= PyDict_GetItemString(pyctx, member);

View File

@@ -32,6 +32,8 @@
#include "bpy_rna.h" /* for setting arg props only - pyrna_py_to_prop() */
#include "bpy_util.h"
#include "BLI_utildefines.h"
#include "RNA_enum_types.h"
#include "WM_api.h"

View File

@@ -27,6 +27,8 @@
#include "WM_api.h"
#include "WM_types.h"
#include "BLI_utildefines.h"
#include "RNA_define.h"
#include "bpy_rna.h"

View File

@@ -26,7 +26,9 @@
#include "bpy_rna.h"
#include "bpy_util.h"
#include "BKE_utildefines.h"
#include "BLI_utildefines.h"
#include "RNA_define.h" /* for defining our own rna */
#include "RNA_enum_types.h"

View File

@@ -21,22 +21,23 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <float.h> /* FLT_MIN/MAX */
#include "bpy_rna.h"
#include "bpy_props.h"
#include "bpy_util.h"
#include "bpy_rna_callback.h"
//#include "blendef.h"
#include "BLI_dynstr.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
#include "float.h" /* FLT_MIN/MAX */
#include "BLI_utildefines.h"
#include "RNA_enum_types.h"
#include "RNA_define.h" /* RNA_def_property_free_identifier */
#include "MEM_guardedalloc.h"
#include "BKE_utildefines.h"
#include "BKE_idcode.h"
#include "BKE_context.h"
#include "BKE_global.h" /* evil G.* */
@@ -57,6 +58,8 @@
#define USE_MATHUTILS
#define USE_STRING_COERCE
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
#ifdef USE_PEDANTIC_WRITE
static short rna_disallow_writes= FALSE;
@@ -91,7 +94,7 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item
#ifdef USE_MATHUTILS
#include "../generic/mathutils.h" /* so we can have mathutils callbacks */
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length);
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length);
static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback);
/* bpyrna vector/euler/quat callbacks */
@@ -1414,20 +1417,34 @@ static int pyrna_prop_collection_bool( BPy_PropertyRNA *self )
static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
{
PointerRNA newptr;
int len= RNA_property_collection_length(&self->ptr, self->prop);
Py_ssize_t keynum_abs= keynum;
if(keynum < 0) keynum += len;
/* notice getting the length of the collection is avoided unless negative index is used
* or to detect internal error with a valid index.
* This is done for faster lookups. */
if(keynum < 0) {
keynum_abs += RNA_property_collection_length(&self->ptr, self->prop);
if(keynum >= 0 && keynum < len) {
if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr)) {
return pyrna_struct_CreatePyObject(&newptr);
}
else { /* fail's if ptr.data == NULL, valid for mesh.materials */
Py_RETURN_NONE;
if(keynum_abs < 0) {
PyErr_Format(PyExc_IndexError, "bpy_prop_collection[%d]: out of range.", keynum);
return NULL;
}
}
PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range, size %d", keynum, len);
return NULL;
if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
return pyrna_struct_CreatePyObject(&newptr);
}
else {
const int len= RNA_property_collection_length(&self->ptr, self->prop);
if(keynum_abs >= len) {
PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range, size %d", keynum, len);
}
else {
PyErr_Format(PyExc_RuntimeError, "bpy_prop_collection[index]: internal error, valid index %d given in %d sized collection but value not found", keynum_abs, len);
}
return NULL;
}
}
static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
@@ -1454,26 +1471,37 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons
}
/* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
static PyObject *pyrna_prop_collection_subscript_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop)
static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
{
PointerRNA newptr;
PyObject *list = PyList_New(stop - start);
int count;
int count= 0;
start = MIN2(start,stop); /* values are clamped from */
PyObject *list= PyList_New(0);
PyObject *item;
for(count = start; count < stop; count++) {
if(RNA_property_collection_lookup_int(ptr, prop, count - start, &newptr)) {
PyList_SET_ITEM(list, count - start, pyrna_struct_CreatePyObject(&newptr));
/* first loop up-until the start */
CollectionPropertyIterator rna_macro_iter;
for(RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
/* PointerRNA itemptr= rna_macro_iter.ptr; */
if(count == start) {
break;
}
else {
Py_DECREF(list);
count++;
}
PyErr_SetString(PyExc_RuntimeError, "error getting an rna struct from a collection");
return NULL;
/* add items until stop */
for(; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
item= pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
PyList_Append(list, item);
Py_DECREF(item);
count++;
if(count == stop) {
break;
}
}
RNA_property_collection_end(&rna_macro_iter);
return list;
}
@@ -1481,7 +1509,7 @@ static PyObject *pyrna_prop_collection_subscript_slice(PointerRNA *ptr, Property
* note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
* since at the moment it reads (and even allocates) the entire array for each index.
*/
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length)
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
{
int count, totdim;
@@ -1567,21 +1595,39 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
return pyrna_prop_collection_subscript_int(self, i);
}
else if (PySlice_Check(key)) {
int len= RNA_property_collection_length(&self->ptr, self->prop);
Py_ssize_t start, stop, step, slicelength;
PySliceObject *key_slice= (PySliceObject *)key;
Py_ssize_t step= 1;
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
if(key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
if (slicelength <= 0) {
return PyList_New(0);
}
else if (step == 1) {
return pyrna_prop_collection_subscript_slice(&self->ptr, self->prop, start, stop);
else if (step != 1) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
return NULL;
}
else if(key_slice->start == Py_None && key_slice->stop == Py_None) {
return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
}
else {
PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported with rna");
return NULL;
Py_ssize_t start= 0, stop= PY_SSIZE_T_MAX;
/* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
if(key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
if(key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) return NULL;
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);
if(start < 0) start += len;
if(stop < 0) start += len;
}
if (stop - start <= 0) {
return PyList_New(0);
}
else {
return pyrna_prop_collection_subscript_slice(self, start, stop);
}
}
}
else {
@@ -1602,21 +1648,34 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject
return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key));
}
else if (PySlice_Check(key)) {
Py_ssize_t start, stop, step, slicelength;
int len = pyrna_prop_array_length(self);
Py_ssize_t step= 1;
PySliceObject *key_slice= (PySliceObject *)key;
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
if(key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
if (slicelength <= 0) {
return PyList_New(0);
}
else if (step == 1) {
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
else if (step != 1) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
return NULL;
}
else if(key_slice->start == Py_None && key_slice->stop == Py_None) {
/* note, no significant advantage with optimizing [:] slice as with collections but include here for consistency with collection slice func */
Py_ssize_t len= (Py_ssize_t)pyrna_prop_array_length(self);
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
}
else {
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported with rna");
return NULL;
int len= pyrna_prop_array_length(self);
Py_ssize_t start, stop, slicelength;
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
return NULL;
if (slicelength <= 0) {
return PyTuple_New(0);
}
else {
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
}
}
}
else {
@@ -3046,7 +3105,7 @@ static PyGetSetDef pyrna_struct_getseters[] = {
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self)
{
PyObject *ret= PyList_New(0);
PyObject *item;
@@ -3071,7 +3130,7 @@ static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
return ret;
}
static PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
{
PyObject *ret= PyList_New(0);
PyObject *item;
@@ -3104,19 +3163,10 @@ static PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
return ret;
}
static PyObject *pyrna_prop_values(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self)
{
PyObject *ret= PyList_New(0);
PyObject *item;
RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
item = pyrna_struct_CreatePyObject(&itemptr);
PyList_Append(ret, item);
Py_DECREF(item);
}
RNA_PROP_END;
return ret;
/* re-use slice*/
return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
}
static char pyrna_struct_get_doc[] =
@@ -3173,7 +3223,7 @@ static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self)
return PyLong_FromVoidPtr(self->ptr.data);
}
static PyObject *pyrna_prop_get(BPy_PropertyRNA *self, PyObject *args)
static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args)
{
PointerRNA newptr;
@@ -3209,7 +3259,7 @@ static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
RNA_PROP_END;
}
/* pyrna_prop_foreach_get/set both use this */
/* pyrna_prop_collection_foreach_get/set both use this */
static int foreach_parse_args(
BPy_PropertyRNA *self, PyObject *args,
@@ -3432,12 +3482,12 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
Py_RETURN_NONE;
}
static PyObject *pyrna_prop_foreach_get(BPy_PropertyRNA *self, PyObject *args)
static PyObject *pyrna_prop_collection_foreach_get(BPy_PropertyRNA *self, PyObject *args)
{
return foreach_getset(self, args, 0);
}
static PyObject *pyrna_prop_foreach_set(BPy_PropertyRNA *self, PyObject *args)
static PyObject *pyrna_prop_collection_foreach_set(BPy_PropertyRNA *self, PyObject *args)
{
return foreach_getset(self, args, 1);
}
@@ -3467,7 +3517,7 @@ PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
/* Try get values from a collection */
PyObject *ret;
PyObject *iter= NULL;
ret = pyrna_prop_values(self);
ret= pyrna_prop_collection_values(self);
/* we know this is a list so no need to PyIter_Check
* otherwise it could be NULL (unlikely) if conversion failed */
@@ -3518,14 +3568,14 @@ static struct PyMethodDef pyrna_prop_array_methods[] = {
};
static struct PyMethodDef pyrna_prop_collection_methods[] = {
{"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL},
{"foreach_set", (PyCFunction)pyrna_prop_foreach_set, METH_VARARGS, NULL},
{"foreach_get", (PyCFunction)pyrna_prop_collection_foreach_get, METH_VARARGS, NULL},
{"foreach_set", (PyCFunction)pyrna_prop_collection_foreach_set, METH_VARARGS, NULL},
{"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, NULL},
{"items", (PyCFunction)pyrna_prop_items, METH_NOARGS,NULL},
{"values", (PyCFunction)pyrna_prop_values, METH_NOARGS, NULL},
{"keys", (PyCFunction)pyrna_prop_collection_keys, METH_NOARGS, NULL},
{"items", (PyCFunction)pyrna_prop_collection_items, METH_NOARGS,NULL},
{"values", (PyCFunction)pyrna_prop_collection_values, METH_NOARGS, NULL},
{"get", (PyCFunction)pyrna_prop_get, METH_VARARGS, NULL},
{"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
};
@@ -4796,7 +4846,7 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
PyObject *list, *name;
PyMethodDef *meth;
list= pyrna_prop_keys(self); /* like calling structs.keys(), avoids looping here */
list= pyrna_prop_collection_keys(self); /* like calling structs.keys(), avoids looping here */
for(meth=pyrna_basetype_methods; meth->ml_name; meth++) {
name = PyUnicode_FromString(meth->ml_name);
@@ -5176,7 +5226,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
return 0;
}
extern void BPY_update_modules(bContext *C); //XXX temp solution
extern void BPY_modules_update(bContext *C); //XXX temp solution
/* TODO - multiple return values like with rna functions */
static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
@@ -5416,12 +5466,13 @@ static void bpy_class_free(void *pyob_ptr)
if(PyErr_Occurred())
PyErr_Clear();
#if 0 /* needs further investigation, too annoying so quiet for now */
if(G.f&G_DEBUG) {
if(self->ob_refcnt > 1) {
PyC_ObSpit("zombie class - ref should be 1", self);
}
}
#endif
Py_DECREF((PyObject *)pyob_ptr);
PyGILState_Release(gilstate);
@@ -5541,7 +5592,10 @@ static PyObject *pyrna_basetype_register(PyObject *UNUSED(self), PyObject *py_cl
if(BPy_reports_to_error(&reports, TRUE))
return NULL;
BKE_assert(srna_new != NULL);
/* python errors validating are not converted into reports so the check above will fail.
* the cause for returning NULL will be printed as an error */
if(srna_new == NULL)
return NULL;
pyrna_subtype_set_rna(py_class, srna_new); /* takes a ref to py_class */

View File

@@ -26,8 +26,10 @@
#include "bpy_rna.h"
#include "bpy_util.h"
#include "BLI_utildefines.h"
#include "DNA_screen_types.h"
#include "BKE_utildefines.h"
#include "BKE_context.h"
#include "ED_space_api.h"

View File

@@ -27,11 +27,10 @@
*/
/* python, will come back */
//void BPY_run_python_script(void) {}
//void BPY_start_python(void) {}
void BPY_call_importloader(const char *filepath) {(void)filepath;}
//void BPY_free_compiled_text(void) {}
void BPY_pyconstraint_eval(void) {}
//void BPY_script_exec(void) {}
//void BPY_python_start(void) {}
//void BPY_text_free_code(void) {}
void BPY_pyconstraint_exec(void) {}
void BPY_pyconstraint_target(void) {}
int BPY_is_pyconstraint(void) {return 0;}
void BPY_pyconstraint_update(void) {}