diff options
Diffstat (limited to 'source/blender/python/intern')
-rw-r--r-- | source/blender/python/intern/bpy.c | 2 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_interface.c | 34 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 156 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna_callback.c | 29 |
4 files changed, 125 insertions, 96 deletions
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 6d2e45f352a..8319213a789 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -67,7 +67,7 @@ PyObject *bpy_script_paths(PyObject *self) static char bpy_blend_paths_doc[] = ".. function:: blend_paths(absolute=False)\n" "\n" -" Returns a list of paths associated with this blend file.\n" +" Returns a list of paths to external files referenced by the loaded .blend file.\n" "\n" " :arg absolute: When true the paths returned are made absolute.\n" " :type absolute: boolean\n" diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index d20f2a23664..af2b5b41961 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -146,28 +146,6 @@ void BPY_update_modules( void ) bpy_context_module->ptr.data= (void *)BPy_GetContext(); } -/***************************************************************************** -* Description: This function creates a new Python dictionary object. -* note: dict is owned by sys.modules["__main__"] module, reference is borrowed -* note: important we use the dict from __main__, this is what python expects - for 'pickle' to work as well as strings like this... - >> foo = 10 - >> print(__import__("__main__").foo) -*****************************************************************************/ -static PyObject *CreateGlobalDictionary(bContext *C, const char *filename) -{ - PyInterpreterState *interp= PyThreadState_GET()->interp; - PyObject *mod_main= PyModule_New("__main__"); - PyDict_SetItemString(interp->modules, "__main__", mod_main); - Py_DECREF(mod_main); /* sys.modules owns now */ - - PyModule_AddObject(mod_main, "__builtins__", interp->builtins); - PyModule_AddStringConstant(mod_main, "__name__", "__main__"); - PyModule_AddStringConstant(mod_main, "__file__", filename); /* __file__ only for nice UI'ness */ - - return PyModule_GetDict(mod_main); -} - /* must be called before Py_Initialize */ void BPY_start_python_path(void) { @@ -329,13 +307,13 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc if (fn==NULL && text==NULL) { return 0; } - + bpy_context_set(C, &gilstate); if (text) { char fn_dummy[FILE_MAXDIR]; bpy_text_filename_get(fn_dummy, text); - py_dict = CreateGlobalDictionary(C, fn_dummy); + py_dict = bpy_namespace_dict_new(fn_dummy); if( !text->compiled ) { /* if it wasn't already compiled, do it now */ char *buf = txt_to_buf( text ); @@ -356,7 +334,7 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc else { FILE *fp= fopen(fn, "r"); - py_dict = CreateGlobalDictionary(C, fn); + py_dict = bpy_namespace_dict_new(fn); if(fp) { #ifdef _WIN32 @@ -500,7 +478,7 @@ int BPY_run_python_script_space(const char *modulename, const char *func) gilstate = PyGILState_Ensure(); - py_dict = CreateGlobalDictionary(C); + py_dict = bpy_namespace_dict_new("<dummy>"); PyObject *module = PyImport_ImportModule(scpt->script.filename); if (module==NULL) { @@ -552,7 +530,7 @@ int BPY_eval_button(bContext *C, const char *expr, double *value) bpy_context_set(C, &gilstate); - py_dict= CreateGlobalDictionary(C, "<blender button>"); + py_dict= bpy_namespace_dict_new("<blender button>"); mod = PyImport_ImportModule("math"); if (mod) { @@ -623,7 +601,7 @@ int BPY_eval_string(bContext *C, const char *expr) bpy_context_set(C, &gilstate); - py_dict= CreateGlobalDictionary(C, "<blender string>"); + py_dict= bpy_namespace_dict_new("<blender string>"); retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 8be9cc4cdae..ff273fa098d 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -4388,7 +4388,7 @@ static int rna_function_arg_count(FunctionRNA *func) const ListBase *lb= RNA_function_defined_parameters(func); PropertyRNA *parm; Link *link; - int count= 1; + int count= (RNA_function_flag(func) & FUNC_NO_SELF) ? 0 : 1; for(link=lb->first; link; link=link->next) { parm= (PropertyRNA*)link; @@ -4409,7 +4409,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun const char *class_type= RNA_struct_identifier(srna); PyObject *py_class= (PyObject*)py_data; PyObject *base_class= RNA_struct_py_type_get(srna); - PyObject *item, *fitem; + PyObject *item; PyObject *py_arg_count; int i, flag, arg_count, func_arg_count; const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; // __name__ @@ -4446,25 +4446,33 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun PyErr_Clear(); } else { - Py_DECREF(item); /* no need to keep a ref, the class owns it */ - - if (PyMethod_Check(item)) - fitem= PyMethod_Function(item); /* py 2.x */ - else - fitem= item; /* py 3.x */ - - if (PyFunction_Check(fitem)==0) { - PyErr_Format( PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a function", class_type, py_class_name, RNA_function_identifier(func)); - return -1; + 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 (PyMethod_Check(item)==0) { + PyErr_Format( PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a method, not a %.200s", class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name); + return -1; + } + item= ((PyMethodObject *)item)->im_func; + } + else { + if (PyFunction_Check(item)==0) { + PyErr_Format( PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a function, not a %.200s", class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name); + return -1; + } } func_arg_count= rna_function_arg_count(func); if (func_arg_count >= 0) { /* -1 if we dont care*/ - py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(fitem), "co_argcount"); + py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(item), "co_argcount"); arg_count = PyLong_AsSsize_t(py_arg_count); Py_DECREF(py_arg_count); + /* note, the number of args we check for and the number of args we give to + * @classmethods are different (quirk of python), this is why rna_function_arg_count() doesn't return the value -1*/ + if(flag & FUNC_NO_SELF) + func_arg_count++; + if (arg_count != func_arg_count) { PyErr_Format( PyExc_AttributeError, "expected %.200s, %.200s class \"%.200s\" function to have %d args, found %d", class_type, py_class_name, RNA_function_identifier(func), func_arg_count, arg_count); return -1; @@ -4537,6 +4545,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par ParameterIterator iter; PointerRNA funcptr; int err= 0, i, flag, ret_len=0; + int is_static = RNA_function_flag(func) & FUNC_NO_SELF; PropertyRNA *pret_single= NULL; void *retdata_single= NULL; @@ -4544,55 +4553,64 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par PyGILState_STATE gilstate; bContext *C= BPy_GetContext(); // XXX - NEEDS FIXING, QUITE BAD. - bpy_context_set(C, &gilstate); - + py_class= RNA_struct_py_type_get(ptr->type); - /* exception, operators store their PyObjects for re-use */ - if(ptr->data) { - if(RNA_struct_is_a(ptr->type, &RNA_Operator)) { - wmOperator *op= ptr->data; - if(op->py_instance) { - py_class_instance= op->py_instance; - Py_INCREF(py_class_instance); - } - else { - /* store the instance here once its created */ - py_class_instance_store= &op->py_instance; - } - } + /* rare case. can happen when registering subclasses */ + if(py_class==NULL) { + fprintf(stderr, "bpy_class_call(): unable to get python class for rna struct '%.200s'\n", RNA_struct_identifier(ptr->type)); + return -1; } - /* end exception */ - - if(py_class_instance==NULL) - py_srna= pyrna_struct_CreatePyObject(ptr); + + bpy_context_set(C, &gilstate); - if(py_class_instance) { - /* special case, instance is cached */ - } - else if(py_srna == NULL) { - py_class_instance = NULL; - } - else if(py_srna == Py_None) { /* probably wont ever happen but possible */ - Py_DECREF(py_srna); - py_class_instance = NULL; - } - else { - args = PyTuple_New(1); - PyTuple_SET_ITEM(args, 0, py_srna); - py_class_instance= PyObject_Call(py_class, args, NULL); - Py_DECREF(args); - - if(py_class_instance == NULL) { - err= -1; /* so the error is not overridden below */ + if (!is_static) { + /* exception, operators store their PyObjects for re-use */ + if(ptr->data) { + if(RNA_struct_is_a(ptr->type, &RNA_Operator)) { + wmOperator *op= ptr->data; + if(op->py_instance) { + py_class_instance= op->py_instance; + Py_INCREF(py_class_instance); + } + else { + /* store the instance here once its created */ + py_class_instance_store= &op->py_instance; + } + } + } + /* end exception */ + + if(py_class_instance==NULL) + py_srna= pyrna_struct_CreatePyObject(ptr); + + if(py_class_instance) { + /* special case, instance is cached */ + } + else if(py_srna == NULL) { + py_class_instance = NULL; } - else if(py_class_instance_store) { - *py_class_instance_store = py_class_instance; - Py_INCREF(py_class_instance); + else if(py_srna == Py_None) { /* probably wont ever happen but possible */ + Py_DECREF(py_srna); + py_class_instance = NULL; + } + else { + args = PyTuple_New(1); + PyTuple_SET_ITEM(args, 0, py_srna); + py_class_instance= PyObject_Call(py_class, args, NULL); + Py_DECREF(args); + + if(py_class_instance == NULL) { + err= -1; /* so the error is not overridden below */ + } + else if(py_class_instance_store) { + *py_class_instance_store = py_class_instance; + Py_INCREF(py_class_instance); + } } } - if (py_class_instance) { /* Initializing the class worked, now run its invoke function */ + if (is_static || py_class_instance) { /* Initializing the class worked, now run its invoke function */ PyObject *item= PyObject_GetAttrString(py_class, RNA_function_identifier(func)); // flag= RNA_function_flag(func); @@ -4600,12 +4618,19 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par RNA_pointer_create(NULL, &RNA_Function, func, &funcptr); args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */ - PyTuple_SET_ITEM(args, 0, py_class_instance); + + if(is_static) { + i= 0; + } + else { + PyTuple_SET_ITEM(args, 0, py_class_instance); + i= 1; + } RNA_parameter_list_begin(parms, &iter); /* parse function parameters */ - for (i= 1; iter.valid; RNA_parameter_list_next(&iter)) { + for (; iter.valid; RNA_parameter_list_next(&iter)) { parm= iter.parm; flag= RNA_property_flag(parm); @@ -4736,7 +4761,16 @@ void pyrna_alloc_types(void) prop = RNA_struct_find_property(&ptr, "structs"); RNA_PROP_BEGIN(&ptr, itemptr, prop) { - Py_DECREF(pyrna_struct_Subtype(&itemptr)); + PyObject *item= pyrna_struct_Subtype(&itemptr); + if(item == NULL) { + if(PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + } + } + else { + Py_DECREF(item); + } } RNA_PROP_END; @@ -4799,6 +4833,14 @@ static PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class) if(srna==NULL) return NULL; + /* fails in cases, cant use this check but would like to :| */ + /* + if(RNA_struct_py_type_get(srna)) { + PyErr_Format(PyExc_ValueError, "bpy.types.register(...): %.200s's parent class %.200s is alredy registered, this is not allowed.", ((PyTypeObject*)py_class)->tp_name, RNA_struct_identifier(srna)); + return NULL; + } + */ + /* check that we have a register callback for this type */ reg= RNA_struct_register(srna); diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c index 2404442dc18..b2a7511f998 100644 --- a/source/blender/python/intern/bpy_rna_callback.c +++ b/source/blender/python/intern/bpy_rna_callback.c @@ -64,19 +64,28 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args) char *cb_event_str= NULL; int cb_event; - if (!PyArg_ParseTuple(args, "OO|s:bpy_struct.callback_add", &cb_func, &cb_args, &cb_event_str)) + if (!PyArg_ParseTuple(args, "OO!|s:bpy_struct.callback_add", &cb_func, &PyTuple_Type, &cb_args, &cb_event_str)) return NULL; + + if(!PyCallable_Check(cb_func)) { + PyErr_SetString(PyExc_TypeError, "callback_add(): first argument isn't callable"); + return NULL; + } if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) { - - static EnumPropertyItem region_draw_mode_items[] = { - {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Pose View", ""}, - {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""}, - {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""}, - {0, NULL, 0, NULL, NULL}}; - - if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) - return NULL; + if(cb_event_str) { + static EnumPropertyItem region_draw_mode_items[] = { + {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""}, + {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""}, + {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""}, + {0, NULL, 0, NULL, NULL}}; + + if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) + return NULL; + } + else { + cb_event= REGION_DRAW_POST_PIXEL; + } handle= ED_region_draw_cb_activate(((ARegion *)self->ptr.data)->type, cb_region_draw, (void *)args, cb_event); Py_INCREF(args); |