From 3aab50f775e4928d3ee525a999e2b4c995ae9ae4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Mar 2009 22:22:58 +0000 Subject: * removed warnings and fixed some python refcount errors * operator class names - Changed 'name' to '__label__' (since __name__ is already used for the class name) - Changed 'properties' to '__props__' * added a PyObject_GetAttrStringArgs(), utility function which Id like to see in pythons C api. PyObject_GetAttrStringArgs(pyob, "someattr", "foo", "bar") /* pyob.someattr.foo.bar */ --- source/blender/python/intern/bpy_interface.c | 1 + source/blender/python/intern/bpy_operator.c | 2 +- source/blender/python/intern/bpy_opwrapper.c | 76 ++++++++++++++------------ source/blender/python/intern/bpy_rna.c | 10 ++-- source/blender/python/intern/bpy_ui.c | 1 - source/blender/python/intern/bpy_util.c | 80 +++++++++++++++++++--------- source/blender/python/intern/bpy_util.h | 3 ++ 7 files changed, 105 insertions(+), 68 deletions(-) diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 54f7bb55cc0..8f01d60ad4b 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -264,6 +264,7 @@ int BPY_run_python_script_space(const char *modulename, const char *func) 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); } diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index d2dbd6c91bb..a35c5ed2cb4 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -110,7 +110,7 @@ int PYOP_props_from_dict(PointerRNA *ptr, PyObject *kw) static PyObject *pyop_base_dir(PyObject *self); static struct PyMethodDef pyop_base_methods[] = { {"__dir__", (PyCFunction)pyop_base_dir, METH_NOARGS, ""}, - {"add", (PyCFunction)PYOP_wrap_add, METH_VARARGS, ""}, + {"add", (PyCFunction)PYOP_wrap_add, METH_O, ""}, {"remove", (PyCFunction)PYOP_wrap_remove, METH_O, ""}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/python/intern/bpy_opwrapper.c b/source/blender/python/intern/bpy_opwrapper.c index 328864ac8b8..379fda35bb6 100644 --- a/source/blender/python/intern/bpy_opwrapper.c +++ b/source/blender/python/intern/bpy_opwrapper.c @@ -40,6 +40,11 @@ #include "bpy_compat.h" #include "bpy_util.h" +#define PYOP_ATTR_PROP "__props__" +#define PYOP_ATTR_UINAME "__label__" +#define PYOP_ATTR_IDNAME "__name__" /* use pythons class name */ +#define PYOP_ATTR_DESCRIPTION "__doc__" /* use pythons docstring */ + typedef struct PyOperatorType { void *next, *prev; char idname[OP_MAX_TYPENAME]; @@ -316,17 +321,16 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) ot->pyop_data= userdata; - // TODO - set properties - + props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP); - if ((props=PyObject_GetAttrString(py_class, "properties"))) { + if (props) { PyObject *dummy_args = PyTuple_New(0); - int i; + Py_DECREF(props); + for(i=0; idata) = newclass; /* Store for later use */ + BPy_RNA_PYTYPE(ptr->data) = (void *)newclass; /* Store for later use */ /* Not 100% needed but useful, * having an instance within a type looks wrong however this instance IS an rna type */ @@ -1198,8 +1198,8 @@ PyObject *BPY_rna_doc( void ) if (type) { name = PyObject_GetAttrString(type, "__name__"); /* myClass.__name__ */ if (name) { - PyDict_SetItem(dict, name, type); Py_DECREF(name); + PyDict_SetItem(dict, name, type); } else { printf("could not get type __name__\n"); @@ -1222,7 +1222,7 @@ PyObject *BPY_rna_doc( void ) * This isnt incorrect since its a python object - but be careful */ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) { - static char *kwlist[] = {"attribute", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL}; + static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL}; char *id, *name="", *description=""; float min=FLT_MIN, max=FLT_MAX, soft_min=FLT_MIN, soft_max=FLT_MAX, def=0.0f; @@ -1249,7 +1249,7 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) { - static char *kwlist[] = {"attribute", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL}; + static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL}; char *id, *name="", *description=""; int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, def=0; @@ -1276,7 +1276,7 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) { - static char *kwlist[] = {"attribute", "name", "description", "default", NULL}; + static char *kwlist[] = {"attr", "name", "description", "default", NULL}; char *id, *name="", *description=""; int def=0; diff --git a/source/blender/python/intern/bpy_ui.c b/source/blender/python/intern/bpy_ui.c index d9df8820e95..ca61c0b425b 100644 --- a/source/blender/python/intern/bpy_ui.c +++ b/source/blender/python/intern/bpy_ui.c @@ -418,7 +418,6 @@ static struct PyMethodDef ui_methods[] = { {"registerKey", (PyCFunction)Method_registerKey, METH_VARARGS, ""}, // XXX could have this in another place too - {"getRegonPtr", (PyCFunction)Method_getRegonPtr, METH_NOARGS, ""}, // XXX Nasty, we really need to improve dealing with context! {"getAreaPtr", (PyCFunction)Method_getAreaPtr, METH_NOARGS, ""}, {"getScreenPtr", (PyCFunction)Method_getScreenPtr, METH_NOARGS, ""}, diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 724c99098f4..47ac739eac0 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -175,39 +175,67 @@ void PyLineSpit(void) { void BPY_getFileAndNum(char **filename, int *lineno) { PyObject *getframe, *frame; - PyObject *f_lineno, *f_code, *co_filename; + PyObject *f_lineno= NULL, *co_filename= NULL; if (filename) *filename= NULL; if (lineno) *lineno = -1; getframe = PySys_GetObject("_getframe"); // borrowed - if (getframe) { - frame = PyObject_CallObject(getframe, NULL); - if (frame) { - f_lineno= PyObject_GetAttrString(frame, "f_lineno"); - f_code= PyObject_GetAttrString(frame, "f_code"); - if (f_lineno && f_code) { - co_filename= PyObject_GetAttrString(f_code, "co_filename"); - if (co_filename) { - - if (filename) *filename = _PyUnicode_AsString(co_filename); - if (lineno) *lineno = (int)PyLong_AsSsize_t(f_lineno); - - Py_DECREF(f_lineno); - Py_DECREF(f_code); - Py_DECREF(co_filename); - Py_DECREF(frame); - - return; - } - } + if (getframe==NULL) { + return; + } + + frame = PyObject_CallObject(getframe, NULL); + if (frame==NULL) + return; + + if (filename) { + co_filename= PyObject_GetAttrStringArgs(frame, 1, "f_code", "co_filename"); + if (co_filename==NULL) { + PyErr_SetString(PyExc_SystemError, "Could not access sys._getframe().f_code.co_filename"); + Py_DECREF(frame); + return; } + + *filename = _PyUnicode_AsString(co_filename); + Py_DECREF(co_filename); } - Py_XDECREF(co_filename); - Py_XDECREF(f_lineno); - Py_XDECREF(f_code); - Py_XDECREF(frame); + if (lineno) { + f_lineno= PyObject_GetAttrString(frame, "f_lineno"); + if (f_lineno==NULL) { + PyErr_SetString(PyExc_SystemError, "Could not access sys._getframe().f_lineno"); + Py_DECREF(frame); + return; + } + + *lineno = (int)PyLong_AsSsize_t(f_lineno); + Py_DECREF(f_lineno); + } +} + +/* Would be nice if python had this built in */ +PyObject *PyObject_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...) +{ + Py_ssize_t i; + PyObject *item= o; + char *attr; + + va_list vargs; + + va_start(vargs, n); + for (i=0; i