[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20991] branches/blender2.5/blender: 2. 5 Python
Brecht Van Lommel
brecht at blender.org
Thu Jun 18 21:51:22 CEST 2009
Revision: 20991
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20991
Author: blendix
Date: 2009-06-18 21:51:22 +0200 (Thu, 18 Jun 2009)
Log Message:
-----------
2.5 Python
Merging changes made by Arystanbek in the soc-2009-kazanbas branch,
plus some things modified and added by me.
* Operator exec is called execute in python now, due to conflicts
with python exec keyword.
* Operator invoke/execute now get context argument.
* Fix crash executing operators due to bpy_import_main_set not being
set with Main pointer.
* The bpy.props module now has the FloatProperty/IntProperty/
StringProperty/BoolProperty functions to define RNA properties for
operators.
* Operators now have an __operator__ property to get the actual RNA
operator pointers, this is only temporary though.
* bpy.ops.add now allows the operator to be already registered, it
will simply overwrite the existing one.
* Both the ui and io directories are now scanned and run on startup.
Modified Paths:
--------------
branches/blender2.5/blender/SConstruct
branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c
branches/blender2.5/blender/source/blender/python/intern/bpy_operator_wrap.c
branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c
branches/blender2.5/blender/source/blender/python/intern/bpy_rna.h
branches/blender2.5/blender/source/blender/python/intern/bpy_util.c
Modified: branches/blender2.5/blender/SConstruct
===================================================================
--- branches/blender2.5/blender/SConstruct 2009-06-18 19:48:55 UTC (rev 20990)
+++ branches/blender2.5/blender/SConstruct 2009-06-18 19:51:22 UTC (rev 20991)
@@ -468,28 +468,18 @@
dotblenderinstall.append(env.Install(dir=td, source=srcfile))
if env['WITH_BF_PYTHON']:
- #-- .blender/scripts
- scriptpath='release/scripts'
- for dp, dn, df in os.walk(scriptpath):
- if 'CVS' in dn:
- dn.remove('CVS')
- if '.svn' in dn:
- dn.remove('.svn')
- dir=env['BF_INSTALLDIR']+'/.blender/scripts'+dp[len(scriptpath):]
- source=[dp+os.sep+f for f in df]
- scriptinstall.append(env.Install(dir=dir,source=source))
+ #-- .blender/scripts, .blender/ui, .blender/io
+ scriptpaths=['release/scripts', 'release/ui', 'release/io']
+ for scriptpath in scriptpaths:
+ for dp, dn, df in os.walk(scriptpath):
+ if 'CVS' in dn:
+ dn.remove('CVS')
+ if '.svn' in dn:
+ dn.remove('.svn')
+ dir=env['BF_INSTALLDIR']+'/.blender/'+os.path.basename(scriptpath)+dp[len(scriptpath):]
+ source=[dp+os.sep+f for f in df]
+ scriptinstall.append(env.Install(dir=dir,source=source))
- #-- .blender/ui
- scriptpath='release/ui'
- for dp, dn, df in os.walk(scriptpath):
- if 'CVS' in dn:
- dn.remove('CVS')
- if '.svn' in dn:
- dn.remove('.svn')
- dir=env['BF_INSTALLDIR']+'/.blender/ui'+dp[len(scriptpath):]
- source=[dp+os.sep+f for f in df]
- scriptinstall.append(env.Install(dir=dir,source=source))
-
#-- icons
if env['OURPLATFORM']=='linux2':
iconlist = []
Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c 2009-06-18 19:48:55 UTC (rev 20990)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c 2009-06-18 19:51:22 UTC (rev 20991)
@@ -59,6 +59,7 @@
PyModule_AddObject( mod, "data", BPY_rna_module() );
/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
PyModule_AddObject( mod, "types", BPY_rna_types() );
+ PyModule_AddObject( mod, "props", BPY_rna_props() );
PyModule_AddObject( mod, "ops", BPY_operator_module() );
PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant
@@ -103,6 +104,7 @@
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
+ {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
{NULL, NULL, 0, NULL}
};
@@ -369,71 +371,77 @@
DIR *dir;
struct dirent *de;
char *file_extension;
+ char *dirname;
char path[FILE_MAX];
- char *dirname= BLI_gethome_folder("ui");
- int filelen; /* filename length */
+ char *dirs[] = {"io", "ui", NULL};
+ int a, filelen; /* filename length */
PyGILState_STATE gilstate;
PyObject *mod;
PyObject *sys_path_orig;
PyObject *sys_path_new;
-
- if(!dirname)
- return;
-
- dir = opendir(dirname);
- if(!dir)
- return;
-
gilstate = PyGILState_Ensure();
- /* backup sys.path */
- sys_path_orig= PySys_GetObject("path");
- Py_INCREF(sys_path_orig); /* dont free it */
-
- sys_path_new= PyList_New(1);
- PyList_SET_ITEM(sys_path_new, 0, PyUnicode_FromString(dirname));
- PySys_SetObject("path", sys_path_new);
- Py_DECREF(sys_path_new);
-
// XXX - evil, need to access context
BPy_SetContext(C);
bpy_import_main_set(CTX_data_main(C));
-
- while((de = readdir(dir)) != NULL) {
- /* We could stat the file but easier just to let python
- * import it and complain if theres a problem */
+
+ for(a=0; dirs[a]; a++) {
+ dirname= BLI_gethome_folder(dirs[a]);
+
+ if(!dirname)
+ continue;
+
+ dir = opendir(dirname);
+
+ if(!dir)
+ continue;
+
+ /* backup sys.path */
+ sys_path_orig= PySys_GetObject("path");
+ Py_INCREF(sys_path_orig); /* dont free it */
- file_extension = strstr(de->d_name, ".py");
-
- if(file_extension && *(file_extension + 3) == '\0') {
- filelen = strlen(de->d_name);
- BLI_strncpy(path, de->d_name, filelen-2); /* cut off the .py on copy */
+ sys_path_new= PyList_New(1);
+ PyList_SET_ITEM(sys_path_new, 0, PyUnicode_FromString(dirname));
+ PySys_SetObject("path", sys_path_new);
+ Py_DECREF(sys_path_new);
- mod= PyImport_ImportModuleLevel(path, NULL, NULL, NULL, 0);
- if (mod) {
- if (reload) {
- PyObject *mod_orig= mod;
- mod= PyImport_ReloadModule(mod);
- Py_DECREF(mod_orig);
+ while((de = readdir(dir)) != NULL) {
+ /* We could stat the file but easier just to let python
+ * import it and complain if theres a problem */
+
+ file_extension = strstr(de->d_name, ".py");
+
+ if(file_extension && *(file_extension + 3) == '\0') {
+ filelen = strlen(de->d_name);
+ BLI_strncpy(path, de->d_name, filelen-2); /* cut off the .py on copy */
+
+ mod= PyImport_ImportModuleLevel(path, NULL, NULL, NULL, 0);
+ if (mod) {
+ if (reload) {
+ PyObject *mod_orig= mod;
+ mod= PyImport_ReloadModule(mod);
+ Py_DECREF(mod_orig);
+ }
}
+
+ if(mod) {
+ Py_DECREF(mod); /* could be NULL from reloading */
+ } else {
+ BPy_errors_to_report(NULL); // TODO - reports
+ fprintf(stderr, "unable to import \"%s\" %s/%s\n", path, dirname, de->d_name);
+ }
+
}
-
- if(mod) {
- Py_DECREF(mod); /* could be NULL from reloading */
- } else {
- BPy_errors_to_report(NULL); // TODO - reports
- fprintf(stderr, "unable to import \"%s\" %s/%s\n", path, dirname, de->d_name);
- }
}
+
+ closedir(dir);
+
+ PySys_SetObject("path", sys_path_orig);
+ Py_DECREF(sys_path_orig);
}
-
- closedir(dir);
- PySys_SetObject("path", sys_path_orig);
- Py_DECREF(sys_path_orig);
-
bpy_import_main_set(NULL);
PyGILState_Release(gilstate);
Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_operator_wrap.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_operator_wrap.c 2009-06-18 19:48:55 UTC (rev 20990)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_operator_wrap.c 2009-06-18 19:51:22 UTC (rev 20991)
@@ -40,6 +40,8 @@
#include "bpy_compat.h"
#include "bpy_util.h"
+#include "../generic/bpy_internal_import.h" // our own imports
+
#define PYOP_ATTR_PROP "__props__"
#define PYOP_ATTR_UINAME "__label__"
#define PYOP_ATTR_IDNAME "__name__" /* use pythons class name */
@@ -177,9 +179,12 @@
PyObject *ret= NULL, *py_class_instance, *item= NULL;
int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
PointerRNA ptr_context;
- PyObject *py_context;
+ PointerRNA ptr_operator;
+ PyObject *py_operator;
PyGILState_STATE gilstate = PyGILState_Ensure();
+
+ bpy_import_main_set(CTX_data_main(C));
BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solutuon for this.
@@ -213,20 +218,29 @@
RNA_property_collection_end(&iter);
}
+
+ /* set operator pointer RNA as instance "__operator__" attribute */
+ RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
+ py_operator= pyrna_struct_CreatePyObject(&ptr_operator);
+ PyObject_SetAttrString(py_class_instance, "__operator__", py_operator);
+ Py_DECREF(py_operator);
+
+ RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
-
if (mode==PYOP_INVOKE) {
item= PyObject_GetAttrString(py_class, "invoke");
- args = PyTuple_New(2);
- PyTuple_SET_ITEM(args, 1, pyop_dict_from_event(event));
+ args = PyTuple_New(3);
+
+ // PyTuple_SET_ITEM "steals" object reference, it is
+ // an object passed shouldn't be DECREF'ed
+ PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
+ PyTuple_SET_ITEM(args, 2, pyop_dict_from_event(event));
}
else if (mode==PYOP_EXEC) {
- item= PyObject_GetAttrString(py_class, "exec");
+ item= PyObject_GetAttrString(py_class, "execute");
args = PyTuple_New(2);
- RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
- py_context = pyrna_struct_CreatePyObject(&ptr_context);
- PyTuple_SET_ITEM(args, 1, py_context);
+ PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
}
else if (mode==PYOP_POLL) {
item= PyObject_GetAttrString(py_class, "poll");
@@ -258,7 +272,8 @@
} else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
/* the returned value could not be converted into a flag */
BPy_errors_to_report(op->reports);
-
+
+ ret_flag = OPERATOR_CANCELLED;
}
/* there is no need to copy the py keyword dict modified by
* pyot->py_invoke(), back to the operator props since they are just
@@ -271,7 +286,34 @@
Py_DECREF(ret);
}
+ /* print operator return value */
+ if (mode != PYOP_POLL) {
+ char flag_str[100];
+ char class_name[100];
+ BPY_flag_def *flag_def = pyop_ret_flags;
+
+ strcpy(flag_str, "");
+
+ while(flag_def->name) {
+ if (ret_flag & flag_def->flag) {
+ if(flag_str[1])
+ sprintf(flag_str, "%s | %s", flag_str, flag_def->name);
+ else
+ strcpy(flag_str, flag_def->name);
+ }
+ flag_def++;
+ }
+
+ /* get class name */
+ item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
+ Py_DECREF(item);
+ strcpy(class_name, _PyUnicode_AsString(item));
+
+ fprintf(stderr, "%s's %s returned %s\n", class_name, mode == PYOP_EXEC ? "execute" : "invoke", flag_str);
+ }
+
PyGILState_Release(gilstate);
+ bpy_import_main_set(NULL);
return ret_flag;
}
@@ -321,7 +363,7 @@
/* api callbacks, detailed checks dont on adding */
if (PyObject_HasAttrString(py_class, "invoke"))
ot->invoke= PYTHON_OT_invoke;
- if (PyObject_HasAttrString(py_class, "exec"))
+ if (PyObject_HasAttrString(py_class, "execute"))
ot->exec= PYTHON_OT_exec;
if (PyObject_HasAttrString(py_class, "poll"))
ot->poll= PYTHON_OT_poll;
@@ -374,6 +416,7 @@
PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
{
PyObject *base_class, *item;
+ wmOperatorType *ot;
char *idname= NULL;
@@ -384,8 +427,8 @@
{PYOP_ATTR_UINAME, 's', 0, BPY_CLASS_ATTR_OPTIONAL},
{PYOP_ATTR_PROP, 'l', 0, BPY_CLASS_ATTR_OPTIONAL},
{PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK},
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list