bpy rna
Calling rna functions with invalid keywords, too many keywords and too many args would fail silently - now raise an error with invalid keywords and a list of valid ones, raise an error when too many args are given. - calling rna functions would alloc a ParameterList each time, changed to use a stack variable (2 pointers and an int). - store the number of parameters ParameterList - python exception types were wrong in many cases, (using attribute error rather then type error) - fixes to small errors in python UI scripts.
This commit is contained in:
@@ -30,13 +30,19 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel):
|
||||
row = split.row(align=True)
|
||||
row.itemR(md, "render", text="")
|
||||
row.itemR(md, "realtime", text="")
|
||||
|
||||
fluid = md.settings
|
||||
|
||||
else:
|
||||
# add modifier
|
||||
split.item_enumO("OBJECT_OT_modifier_add", "type", "FLUID_SIMULATION", text="Add")
|
||||
split.itemL()
|
||||
|
||||
if md:
|
||||
fluid = md.settings
|
||||
|
||||
fluid = None
|
||||
|
||||
|
||||
if fluid:
|
||||
|
||||
|
||||
col = layout.column(align=True)
|
||||
row = col.row()
|
||||
@@ -177,7 +183,11 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel):
|
||||
def poll(self, context):
|
||||
md = context.fluid
|
||||
if md:
|
||||
return (md.settings.type == 'DOMAIN')
|
||||
settings = md.settings
|
||||
if settings:
|
||||
return (settings.type == 'DOMAIN')
|
||||
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -217,7 +227,11 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel):
|
||||
def poll(self, context):
|
||||
md = context.fluid
|
||||
if md:
|
||||
return (md.settings.type == 'DOMAIN')
|
||||
settings = md.settings
|
||||
if settings:
|
||||
return (settings.type == 'DOMAIN')
|
||||
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -244,7 +258,11 @@ class PHYSICS_PT_domain_particles(PhysicButtonsPanel):
|
||||
def poll(self, context):
|
||||
md = context.fluid
|
||||
if md:
|
||||
return (md.settings.type == 'DOMAIN')
|
||||
settings = md.settings
|
||||
if settings:
|
||||
return (settings.type == 'DOMAIN')
|
||||
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
@@ -136,8 +136,8 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel):
|
||||
|
||||
col.itemR(softbody, "new_aero", text="Aero")
|
||||
subcol = col.column()
|
||||
subcol.active = softbody.new_aero
|
||||
subcol.itemR(softbody, "aero", text="Factor", enabled=softbody.new_aero)
|
||||
subcol.enabled = softbody.new_aero
|
||||
subcol.itemR(softbody, "aero", text="Factor")
|
||||
|
||||
col.itemL(text="Collision:")
|
||||
col.itemR(softbody, "edge_collision", text="Edge")
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
#include "console_intern.h" // own include
|
||||
|
||||
static void console_update_rect(bContext *C, ARegion *ar)
|
||||
static void console_update_rect(const bContext *C, ARegion *ar)
|
||||
{
|
||||
SpaceConsole *sc= CTX_wm_space_console(C);
|
||||
View2D *v2d= &ar->v2d;
|
||||
|
||||
@@ -758,8 +758,9 @@ const struct ListBase *RNA_function_defined_parameters(FunctionRNA *func);
|
||||
|
||||
/* Utility */
|
||||
|
||||
ParameterList *RNA_parameter_list_create(PointerRNA *ptr, FunctionRNA *func);
|
||||
ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, FunctionRNA *func);
|
||||
void RNA_parameter_list_free(ParameterList *parms);
|
||||
int RNA_parameter_list_size(ParameterList *parms);
|
||||
|
||||
void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter);
|
||||
void RNA_parameter_list_next(ParameterIterator *iter);
|
||||
|
||||
@@ -163,10 +163,19 @@ typedef struct PropertyRNA PropertyRNA;
|
||||
|
||||
/* Parameter List */
|
||||
|
||||
typedef struct ParameterList ParameterList;
|
||||
typedef struct ParameterList {
|
||||
/* storage for parameters */
|
||||
void *data;
|
||||
|
||||
/* store the parameter count */
|
||||
int tot;
|
||||
|
||||
/* function passed at creation time */
|
||||
struct FunctionRNA *func;
|
||||
} ParameterList;
|
||||
|
||||
typedef struct ParameterIterator {
|
||||
ParameterList *parms;
|
||||
struct ParameterList *parms;
|
||||
PointerRNA funcptr;
|
||||
void *data;
|
||||
int size, offset;
|
||||
@@ -209,7 +218,7 @@ typedef enum StructFlag {
|
||||
} StructFlag;
|
||||
|
||||
typedef int (*StructValidateFunc)(struct PointerRNA *ptr, void *data, int *have_function);
|
||||
typedef int (*StructCallbackFunc)(struct PointerRNA *ptr, struct FunctionRNA *func, struct ParameterList *list);
|
||||
typedef int (*StructCallbackFunc)(struct PointerRNA *ptr, struct FunctionRNA *func, ParameterList *list);
|
||||
typedef void (*StructFreeFunc)(void *data);
|
||||
typedef struct StructRNA *(*StructRegisterFunc)(const struct bContext *C, struct ReportList *reports, void *data,
|
||||
StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free);
|
||||
|
||||
@@ -1404,9 +1404,10 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA
|
||||
#if 0
|
||||
else if(cprop->add){
|
||||
if(!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
|
||||
ParameterList *params= RNA_parameter_list_create(ptr, cprop->add);
|
||||
RNA_function_call(NULL, NULL, ptr, cprop->add, params);
|
||||
RNA_parameter_list_free(params);
|
||||
ParameterList params;
|
||||
RNA_parameter_list_create(¶ms, ptr, cprop->add);
|
||||
RNA_function_call(NULL, NULL, ptr, cprop->add, ¶ms);
|
||||
RNA_parameter_list_free(¶ms);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1453,9 +1454,10 @@ void RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
|
||||
#if 0
|
||||
else if(cprop->remove){
|
||||
if(!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
|
||||
ParameterList *params= RNA_parameter_list_create(ptr, cprop->remove);
|
||||
RNA_function_call(NULL, NULL, ptr, cprop->remove, params);
|
||||
RNA_parameter_list_free(params);
|
||||
ParameterList params;
|
||||
RNA_parameter_list_create(&ptr, cprop->remove);
|
||||
RNA_function_call(NULL, NULL, ptr, cprop->remove, ¶ms);
|
||||
RNA_parameter_list_free(¶ms);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2787,20 +2789,17 @@ const struct ListBase *RNA_function_defined_parameters(FunctionRNA *func)
|
||||
|
||||
/* Utility */
|
||||
|
||||
ParameterList *RNA_parameter_list_create(PointerRNA *ptr, FunctionRNA *func)
|
||||
ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, FunctionRNA *func)
|
||||
{
|
||||
ParameterList *parms;
|
||||
PropertyRNA *parm;
|
||||
int tot;
|
||||
int tot= 0;
|
||||
|
||||
parms= MEM_callocN(sizeof(ParameterList), "ParameterList");
|
||||
|
||||
parm= func->cont.properties.first;
|
||||
for(tot= 0; parm; parm= parm->next)
|
||||
for(parm= func->cont.properties.first; parm; parm= parm->next)
|
||||
tot+= rna_parameter_size(parm);
|
||||
|
||||
parms->data= MEM_callocN(tot, "RNA_parameter_list_create");
|
||||
parms->func= func;
|
||||
parms->tot= tot;
|
||||
|
||||
return parms;
|
||||
}
|
||||
@@ -2822,8 +2821,11 @@ void RNA_parameter_list_free(ParameterList *parms)
|
||||
parms->data= NULL;
|
||||
|
||||
parms->func= NULL;
|
||||
}
|
||||
|
||||
MEM_freeN(parms);
|
||||
int RNA_parameter_list_size(ParameterList *parms)
|
||||
{
|
||||
return parms->tot;
|
||||
}
|
||||
|
||||
void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
|
||||
@@ -3141,7 +3143,7 @@ static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, Prop
|
||||
int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, va_list args)
|
||||
{
|
||||
PointerRNA funcptr;
|
||||
ParameterList *parms;
|
||||
ParameterList parms;
|
||||
ParameterIterator iter;
|
||||
PropertyRNA *pret, *parm;
|
||||
PropertyType type;
|
||||
@@ -3157,8 +3159,8 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
|
||||
pret= RNA_function_return(func);
|
||||
flen= strlen(format);
|
||||
|
||||
parms= RNA_parameter_list_create(ptr, func);
|
||||
RNA_parameter_list_begin(parms, &iter);
|
||||
RNA_parameter_list_create(&parms, ptr, func);
|
||||
RNA_parameter_list_begin(&parms, &iter);
|
||||
|
||||
for(i= 0, ofs= 0; iter.valid; RNA_parameter_list_next(&iter), i++) {
|
||||
parm= iter.parm;
|
||||
@@ -3240,7 +3242,7 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
|
||||
}
|
||||
|
||||
if (err==0)
|
||||
err= RNA_function_call(C, reports, ptr, func, parms);
|
||||
err= RNA_function_call(C, reports, ptr, func, &parms);
|
||||
|
||||
/* XXX throw error when more parameters than those needed are passed or leave silent? */
|
||||
if (err==0 && pret && ofs<flen && format[ofs++]=='R') {
|
||||
@@ -3302,7 +3304,7 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
|
||||
}
|
||||
|
||||
RNA_parameter_list_end(&iter);
|
||||
RNA_parameter_list_free(parms);
|
||||
RNA_parameter_list_free(&parms);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -88,14 +88,6 @@ typedef struct ContainerRNA {
|
||||
ListBase properties;
|
||||
} ContainerRNA;
|
||||
|
||||
struct ParameterList {
|
||||
/* storage for parameters */
|
||||
void *data;
|
||||
|
||||
/* function passed at creation time */
|
||||
FunctionRNA *func;
|
||||
};
|
||||
|
||||
struct FunctionRNA {
|
||||
/* structs are containers of properties */
|
||||
ContainerRNA cont;
|
||||
|
||||
@@ -76,7 +76,7 @@ static ARegionType *region_type_find(ReportList *reports, int space_type, int re
|
||||
static int panel_poll(const bContext *C, PanelType *pt)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
ParameterList *list;
|
||||
ParameterList list;
|
||||
FunctionRNA *func;
|
||||
void *ret;
|
||||
int visible;
|
||||
@@ -84,14 +84,14 @@ static int panel_poll(const bContext *C, PanelType *pt)
|
||||
RNA_pointer_create(NULL, pt->py_srna, NULL, &ptr); /* dummy */
|
||||
func= RNA_struct_find_function(&ptr, "poll");
|
||||
|
||||
list= RNA_parameter_list_create(&ptr, func);
|
||||
RNA_parameter_set_lookup(list, "context", &C);
|
||||
pt->py_call(&ptr, func, list);
|
||||
RNA_parameter_list_create(&list, &ptr, func);
|
||||
RNA_parameter_set_lookup(&list, "context", &C);
|
||||
pt->py_call(&ptr, func, &list);
|
||||
|
||||
RNA_parameter_get_lookup(list, "visible", &ret);
|
||||
RNA_parameter_get_lookup(&list, "visible", &ret);
|
||||
visible= *(int*)ret;
|
||||
|
||||
RNA_parameter_list_free(list);
|
||||
RNA_parameter_list_free(&list);
|
||||
|
||||
return visible;
|
||||
}
|
||||
@@ -99,33 +99,33 @@ static int panel_poll(const bContext *C, PanelType *pt)
|
||||
static void panel_draw(const bContext *C, Panel *pnl)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
ParameterList *list;
|
||||
ParameterList list;
|
||||
FunctionRNA *func;
|
||||
|
||||
RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->py_srna, pnl, &ptr);
|
||||
func= RNA_struct_find_function(&ptr, "draw");
|
||||
|
||||
list= RNA_parameter_list_create(&ptr, func);
|
||||
RNA_parameter_set_lookup(list, "context", &C);
|
||||
pnl->type->py_call(&ptr, func, list);
|
||||
RNA_parameter_list_create(&list, &ptr, func);
|
||||
RNA_parameter_set_lookup(&list, "context", &C);
|
||||
pnl->type->py_call(&ptr, func, &list);
|
||||
|
||||
RNA_parameter_list_free(list);
|
||||
RNA_parameter_list_free(&list);
|
||||
}
|
||||
|
||||
static void panel_draw_header(const bContext *C, Panel *pnl)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
ParameterList *list;
|
||||
ParameterList list;
|
||||
FunctionRNA *func;
|
||||
|
||||
RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->py_srna, pnl, &ptr);
|
||||
func= RNA_struct_find_function(&ptr, "draw_header");
|
||||
|
||||
list= RNA_parameter_list_create(&ptr, func);
|
||||
RNA_parameter_set_lookup(list, "context", &C);
|
||||
pnl->type->py_call(&ptr, func, list);
|
||||
RNA_parameter_list_create(&list, &ptr, func);
|
||||
RNA_parameter_set_lookup(&list, "context", &C);
|
||||
pnl->type->py_call(&ptr, func, &list);
|
||||
|
||||
RNA_parameter_list_free(list);
|
||||
RNA_parameter_list_free(&list);
|
||||
}
|
||||
|
||||
static void rna_Panel_unregister(const bContext *C, StructRNA *type)
|
||||
@@ -210,17 +210,17 @@ static StructRNA* rna_Panel_refine(struct PointerRNA *ptr)
|
||||
static void header_draw(const bContext *C, Header *hdr)
|
||||
{
|
||||
PointerRNA htr;
|
||||
ParameterList *list;
|
||||
ParameterList list;
|
||||
FunctionRNA *func;
|
||||
|
||||
RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->py_srna, hdr, &htr);
|
||||
func= RNA_struct_find_function(&htr, "draw");
|
||||
|
||||
list= RNA_parameter_list_create(&htr, func);
|
||||
RNA_parameter_set_lookup(list, "context", &C);
|
||||
hdr->type->py_call(&htr, func, list);
|
||||
RNA_parameter_list_create(&list, &htr, func);
|
||||
RNA_parameter_set_lookup(&list, "context", &C);
|
||||
hdr->type->py_call(&htr, func, &list);
|
||||
|
||||
RNA_parameter_list_free(list);
|
||||
RNA_parameter_list_free(&list);
|
||||
}
|
||||
|
||||
static void rna_Header_unregister(const bContext *C, StructRNA *type)
|
||||
@@ -301,7 +301,7 @@ static StructRNA* rna_Header_refine(struct PointerRNA *htr)
|
||||
static int menu_poll(const bContext *C, MenuType *pt)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
ParameterList *list;
|
||||
ParameterList list;
|
||||
FunctionRNA *func;
|
||||
void *ret;
|
||||
int visible;
|
||||
@@ -309,14 +309,14 @@ static int menu_poll(const bContext *C, MenuType *pt)
|
||||
RNA_pointer_create(NULL, pt->py_srna, NULL, &ptr); /* dummy */
|
||||
func= RNA_struct_find_function(&ptr, "poll");
|
||||
|
||||
list= RNA_parameter_list_create(&ptr, func);
|
||||
RNA_parameter_set_lookup(list, "context", &C);
|
||||
pt->py_call(&ptr, func, list);
|
||||
RNA_parameter_list_create(&list, &ptr, func);
|
||||
RNA_parameter_set_lookup(&list, "context", &C);
|
||||
pt->py_call(&ptr, func, &list);
|
||||
|
||||
RNA_parameter_get_lookup(list, "visible", &ret);
|
||||
RNA_parameter_get_lookup(&list, "visible", &ret);
|
||||
visible= *(int*)ret;
|
||||
|
||||
RNA_parameter_list_free(list);
|
||||
RNA_parameter_list_free(&list);
|
||||
|
||||
return visible;
|
||||
}
|
||||
@@ -324,17 +324,17 @@ static int menu_poll(const bContext *C, MenuType *pt)
|
||||
static void menu_draw(const bContext *C, Menu *hdr)
|
||||
{
|
||||
PointerRNA mtr;
|
||||
ParameterList *list;
|
||||
ParameterList list;
|
||||
FunctionRNA *func;
|
||||
|
||||
RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->py_srna, hdr, &mtr);
|
||||
func= RNA_struct_find_function(&mtr, "draw");
|
||||
|
||||
list= RNA_parameter_list_create(&mtr, func);
|
||||
RNA_parameter_set_lookup(list, "context", &C);
|
||||
hdr->type->py_call(&mtr, func, list);
|
||||
RNA_parameter_list_create(&list, &mtr, func);
|
||||
RNA_parameter_set_lookup(&list, "context", &C);
|
||||
hdr->type->py_call(&mtr, func, &list);
|
||||
|
||||
RNA_parameter_list_free(list);
|
||||
RNA_parameter_list_free(&list);
|
||||
}
|
||||
|
||||
static void rna_Menu_unregister(const bContext *C, StructRNA *type)
|
||||
|
||||
@@ -367,7 +367,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
|
||||
ret = pyrna_prop_CreatePyObject(ptr, prop);
|
||||
break;
|
||||
default:
|
||||
PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_prop_to_py)", type);
|
||||
PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_prop_to_py)", type);
|
||||
ret = NULL;
|
||||
break;
|
||||
}
|
||||
@@ -392,7 +392,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi
|
||||
if (strcmp(arg_name, "rna_type")==0) continue;
|
||||
|
||||
if (kw==NULL) {
|
||||
PyErr_Format( PyExc_AttributeError, "%.200s: no keywords, expected \"%.200s\"", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
PyErr_Format( PyExc_TypeError, "%.200s: no keywords, expected \"%.200s\"", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
error_val= -1;
|
||||
break;
|
||||
}
|
||||
@@ -400,7 +400,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi
|
||||
item= PyDict_GetItemString(kw, arg_name);
|
||||
|
||||
if (item == NULL) {
|
||||
PyErr_Format( PyExc_AttributeError, "%.200s: keyword \"%.200s\" missing", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
PyErr_Format( PyExc_TypeError, "%.200s: keyword \"%.200s\" missing", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
error_val = -1; /* pyrna_py_to_prop sets the error */
|
||||
break;
|
||||
}
|
||||
@@ -424,7 +424,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi
|
||||
arg_name= NULL;
|
||||
}
|
||||
|
||||
PyErr_Format( PyExc_AttributeError, "%.200s: keyword \"%.200s\" unrecognized", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
PyErr_Format( PyExc_TypeError, "%.200s: keyword \"%.200s\" unrecognized", error_prefix, arg_name ? arg_name : "<UNKNOWN>");
|
||||
error_val = -1;
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
/* done getting the length */
|
||||
|
||||
if (py_len != len) {
|
||||
PyErr_Format(PyExc_AttributeError, "python sequence length %d did not match the RNA array length %d.", py_len, len);
|
||||
PyErr_Format(PyExc_TypeError, "python sequence length %d did not match the RNA array length %d.", py_len, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -647,7 +647,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
else RNA_property_enum_set(ptr, prop, val);
|
||||
} else {
|
||||
char *enum_str= pyrna_enum_as_string(ptr, prop);
|
||||
PyErr_Format(PyExc_AttributeError, "enum \"%.200s\" not found in (%.200s)", param, enum_str);
|
||||
PyErr_Format(PyExc_TypeError, "enum \"%.200s\" not found in (%.200s)", param, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
return -1;
|
||||
}
|
||||
@@ -1807,7 +1807,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
|
||||
PyTuple_SET_ITEM(ret, a, PyFloat_FromDouble( ((float*)data)[a] ));
|
||||
break;
|
||||
default:
|
||||
PyErr_Format(PyExc_AttributeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type);
|
||||
PyErr_Format(PyExc_TypeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type);
|
||||
ret = NULL;
|
||||
break;
|
||||
}
|
||||
@@ -1889,7 +1889,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type);
|
||||
PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type);
|
||||
ret = NULL;
|
||||
break;
|
||||
}
|
||||
@@ -1904,25 +1904,31 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
|
||||
FunctionRNA *self_func= PyCObject_AsVoidPtr(PyTuple_GET_ITEM(self, 1));
|
||||
|
||||
PointerRNA funcptr;
|
||||
ParameterList *parms;
|
||||
ParameterList parms;
|
||||
ParameterIterator iter;
|
||||
PropertyRNA *pret, *parm;
|
||||
PyObject *ret, *item;
|
||||
int i, tlen, flag, err= 0;
|
||||
const char *tid, *fid, *pid;
|
||||
int i, args_len, parms_len, flag, err= 0, kw_tot= 0;
|
||||
const char *parm_id;
|
||||
void *retdata= NULL;
|
||||
|
||||
/* setup */
|
||||
RNA_pointer_create(NULL, &RNA_Function, self_func, &funcptr);
|
||||
|
||||
pret= RNA_function_return(self_func);
|
||||
tlen= PyTuple_GET_SIZE(args);
|
||||
args_len= PyTuple_GET_SIZE(args);
|
||||
|
||||
parms= RNA_parameter_list_create(self_ptr, self_func);
|
||||
RNA_parameter_list_begin(parms, &iter);
|
||||
RNA_parameter_list_create(&parms, self_ptr, self_func);
|
||||
RNA_parameter_list_begin(&parms, &iter);
|
||||
parms_len = RNA_parameter_list_size(&parms);
|
||||
|
||||
if(args_len + (kw ? PyDict_Size(kw):0) > parms_len) {
|
||||
PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): takes at most %d arguments, got %d", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parms_len, args_len);
|
||||
err= -1;
|
||||
}
|
||||
|
||||
/* parse function parameters */
|
||||
for (i= 0; iter.valid; RNA_parameter_list_next(&iter)) {
|
||||
for (i= 0; iter.valid && err==0; RNA_parameter_list_next(&iter)) {
|
||||
parm= iter.parm;
|
||||
|
||||
if (parm==pret) {
|
||||
@@ -1930,27 +1936,27 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
|
||||
continue;
|
||||
}
|
||||
|
||||
pid= RNA_property_identifier(parm);
|
||||
parm_id= RNA_property_identifier(parm);
|
||||
flag= RNA_property_flag(parm);
|
||||
item= NULL;
|
||||
|
||||
if ((i < tlen) && (flag & PROP_REQUIRED)) {
|
||||
if ((i < args_len) && (flag & PROP_REQUIRED)) {
|
||||
item= PyTuple_GET_ITEM(args, i);
|
||||
i++;
|
||||
}
|
||||
else if (kw != NULL)
|
||||
item= PyDict_GetItemString(kw, pid); /* borrow ref */
|
||||
else if (kw != NULL) {
|
||||
item= PyDict_GetItemString(kw, parm_id); /* borrow ref */
|
||||
if(item)
|
||||
kw_tot++; /* make sure invalid keywords are not given */
|
||||
}
|
||||
|
||||
if (item==NULL) {
|
||||
if(flag & PROP_REQUIRED) {
|
||||
tid= RNA_struct_identifier(self_ptr->type);
|
||||
fid= RNA_function_identifier(self_func);
|
||||
|
||||
PyErr_Format(PyExc_AttributeError, "%.200s.%.200s(): required parameter \"%.200s\" not specified", tid, fid, pid);
|
||||
PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): required parameter \"%.200s\" not specified", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parm_id);
|
||||
err= -1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
else /* PyDict_GetItemString wont raise an error */
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1960,6 +1966,73 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Check if we gave args that dont exist in the function
|
||||
* printing the error is slow but it should only happen when developing.
|
||||
* the if below is quick, checking if it passed less keyword args then we gave */
|
||||
if(kw && (PyDict_Size(kw) > kw_tot)) {
|
||||
PyObject *key, *value;
|
||||
Py_ssize_t pos = 0;
|
||||
|
||||
DynStr *bad_args= BLI_dynstr_new();
|
||||
DynStr *good_args= BLI_dynstr_new();
|
||||
|
||||
char *arg_name, *bad_args_str, *good_args_str;
|
||||
int found= 0, first=1;
|
||||
|
||||
while (PyDict_Next(kw, &pos, &key, &value)) {
|
||||
|
||||
arg_name= _PyUnicode_AsString(key);
|
||||
found= 0;
|
||||
|
||||
if(arg_name==NULL) { /* unlikely the argname is not a string but ignore if it is*/
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
/* Search for arg_name */
|
||||
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= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RNA_parameter_list_end(&iter);
|
||||
|
||||
if(!found) {
|
||||
BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name);
|
||||
first= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* list good args */
|
||||
first= 1;
|
||||
|
||||
RNA_parameter_list_begin(&parms, &iter);
|
||||
for(; iter.valid; RNA_parameter_list_next(&iter)) {
|
||||
parm= iter.parm;
|
||||
BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm));
|
||||
first= 0;
|
||||
}
|
||||
RNA_parameter_list_end(&iter);
|
||||
|
||||
|
||||
bad_args_str= BLI_dynstr_get_cstring(bad_args);
|
||||
good_args_str= BLI_dynstr_get_cstring(good_args);
|
||||
|
||||
PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): was called with invalid keyword arguments(s) (%s), expected (%s)", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), bad_args_str, good_args_str);
|
||||
|
||||
BLI_dynstr_free(bad_args);
|
||||
BLI_dynstr_free(good_args);
|
||||
MEM_freeN(bad_args_str);
|
||||
MEM_freeN(good_args_str);
|
||||
|
||||
err= -1;
|
||||
}
|
||||
|
||||
ret= NULL;
|
||||
if (err==0) {
|
||||
/* call function */
|
||||
@@ -1967,20 +2040,26 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
|
||||
bContext *C= BPy_GetContext();
|
||||
|
||||
BKE_reports_init(&reports, RPT_STORE);
|
||||
RNA_function_call(C, &reports, self_ptr, self_func, parms);
|
||||
RNA_function_call(C, &reports, self_ptr, self_func, &parms);
|
||||
|
||||
err= (BPy_reports_to_error(&reports))? -1: 0;
|
||||
BKE_reports_clear(&reports);
|
||||
|
||||
/* return value */
|
||||
if(err==0)
|
||||
if(pret)
|
||||
if(err==0) {
|
||||
if(pret) {
|
||||
ret= pyrna_param_to_py(&funcptr, pret, retdata);
|
||||
|
||||
/* possible there is an error in conversion */
|
||||
if(ret==NULL)
|
||||
err= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
RNA_parameter_list_end(&iter);
|
||||
RNA_parameter_list_free(parms);
|
||||
RNA_parameter_list_free(&parms);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -2387,7 +2466,7 @@ static PyObject *pyrna_basetype_getattro( BPy_BaseTypeRNA * self, PyObject *pyna
|
||||
return ret;
|
||||
}
|
||||
else { /* Override the error */
|
||||
PyErr_Format(PyExc_AttributeError, "bpy.types.%.200s not a valid RNA_Struct", _PyUnicode_AsString(pyname));
|
||||
PyErr_Format(PyExc_AttributeError, "bpy.types.%.200s RNA_Struct does not exist", _PyUnicode_AsString(pyname));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -2629,7 +2708,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
|
||||
if (base_class) {
|
||||
if (!PyObject_IsSubclass(py_class, base_class)) {
|
||||
PyObject *name= PyObject_GetAttrString(base_class, "__name__");
|
||||
PyErr_Format( PyExc_AttributeError, "expected %.200s subclass of class \"%.200s\"", class_type, name ? _PyUnicode_AsString(name):"<UNKNOWN>");
|
||||
PyErr_Format( PyExc_TypeError, "expected %.200s subclass of class \"%.200s\"", class_type, name ? _PyUnicode_AsString(name):"<UNKNOWN>");
|
||||
Py_XDECREF(name);
|
||||
return -1;
|
||||
}
|
||||
@@ -2667,7 +2746,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
|
||||
fitem= item; /* py 3.x */
|
||||
|
||||
if (PyFunction_Check(fitem)==0) {
|
||||
PyErr_Format( PyExc_AttributeError, "expected %.200s class \"%.200s\" attribute to be a function", class_type, RNA_function_identifier(func));
|
||||
PyErr_Format( PyExc_TypeError, "expected %.200s class \"%.200s\" attribute to be a function", class_type, RNA_function_identifier(func));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2795,12 +2874,12 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
|
||||
}
|
||||
else {
|
||||
Py_DECREF(py_class_instance);
|
||||
PyErr_Format(PyExc_AttributeError, "could not find function %.200s in %.200s to execute callback.", RNA_function_identifier(func), RNA_struct_identifier(ptr->type));
|
||||
PyErr_Format(PyExc_TypeError, "could not find function %.200s in %.200s to execute callback.", RNA_function_identifier(func), RNA_struct_identifier(ptr->type));
|
||||
err= -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_AttributeError, "could not create instance of %.200s to call callback function %.200s.", RNA_struct_identifier(ptr->type), RNA_function_identifier(func));
|
||||
PyErr_Format(PyExc_RuntimeError, "could not create instance of %.200s to call callback function %.200s.", RNA_struct_identifier(ptr->type), RNA_function_identifier(func));
|
||||
err= -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user