changes python initialization
authorCampbell Barton <ideasman42@gmail.com>
Fri, 13 Nov 2009 09:28:05 +0000 (09:28 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 13 Nov 2009 09:28:05 +0000 (09:28 +0000)
- bpy is now a python package, this makes it easier to add utility modules and adjust python startup which was previously using verbose Py/C api. Access should not be any slower since both C and Python modules use dictionary access.
- loop over scripts and load via python (currently F8 reload isnt working, will add back shortly)
- the C module is kept but renamed to _bpy and not meant for direct access from anything but the bpy package.
- bpy_types.py is an exception since it runs before the bpy package is initialized.

13 files changed:
release/scripts/io/netrender/__init__.py
release/scripts/modules/bpy/__init__.py [new file with mode: 0644]
release/scripts/modules/bpy/ops.py [moved from release/scripts/modules/bpy_ops.py with 94% similarity]
release/scripts/modules/bpy/utils.py [moved from release/scripts/modules/bpy_utils.py with 91% similarity]
release/scripts/modules/bpy_ext/Mesh.py [deleted file]
release/scripts/modules/bpy_ext/Object.py [deleted file]
release/scripts/modules/bpy_ext/__init__.py [deleted file]
release/scripts/modules/bpy_types.py
source/blender/editors/space_script/script_edit.c
source/blender/python/BPY_extern.h
source/blender/python/intern/bpy_interface.c
source/blender/python/intern/stubs.c
source/creator/creator.c

index be3d25d..3a17052 100644 (file)
 
 # This directory is a Python package.
 
-import model
-import operators
-import client
-import slave
-import master
-import master_html
-import utils
-import balancing
-import ui
+from netrender import model
+from netrender import operators
+from netrender import client
+from netrender import slave
+from netrender import master
+from netrender import master_html
+from netrender import utils
+from netrender import balancing
+from netrender import ui
 
 # store temp data in bpy module
 
diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py
new file mode 100644 (file)
index 0000000..aa755bb
--- /dev/null
@@ -0,0 +1,50 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# internal blender C module
+import _bpy
+from _bpy import types, props
+
+data = _bpy.data
+context = _bpy.context
+
+# python modules
+from bpy import utils, ops
+
+# fake operator module
+ops = ops.bpy_ops()
+
+# load all scripts
+import os
+import sys
+
+base_path = os.path.join(os.path.dirname(__file__), "..", "..")
+base_path = os.path.normpath(base_path) # clean
+
+# print(base_path, base_path_ui)
+
+for path_subdir in ("ui", "op", "io"):
+    path = os.path.join(base_path, path_subdir)
+    sys.path.insert(0, path)
+    for f in sorted(os.listdir(path)):
+        if f.endswith(".py"):
+            # python module
+            __import__(f[0:-3])
+        elif "." not in f:
+            # python package
+            __import__(f)
similarity index 94%
rename from release/scripts/modules/bpy_ops.py
rename to release/scripts/modules/bpy/ops.py
index 35d986f..e3fa2ab 100644 (file)
 # <pep8-80 compliant>
 
 # for slightly faster access
-from bpy.__ops__ import add        as op_add
-from bpy.__ops__ import remove     as op_remove
-from bpy.__ops__ import dir        as op_dir
-from bpy.__ops__ import call       as op_call
-from bpy.__ops__ import as_string  as op_as_string
-from bpy.__ops__ import get_rna    as op_get_rna
+from _bpy import ops as ops_module
+
+op_add = ops_module.add
+op_remove = ops_module.remove
+op_dir = ops_module.dir
+op_call = ops_module.call
+op_as_string = ops_module.as_string
+op_get_rna = ops_module.get_rna
 
 # Keep in sync with WM_types.h
 context_dict = {
@@ -192,3 +194,4 @@ class bpy_ops_submodule_op(object):
 
 import bpy
 bpy.ops = bpy_ops()
+
similarity index 91%
rename from release/scripts/modules/bpy_utils.py
rename to release/scripts/modules/bpy/utils.py
index 5a73364..8509bf1 100644 (file)
@@ -25,6 +25,3 @@ def expandpath(path):
 
     return path
 
-import types
-bpy.utils = types.ModuleType("bpy.utils")
-bpy.utils.expandpath = expandpath
diff --git a/release/scripts/modules/bpy_ext/Mesh.py b/release/scripts/modules/bpy_ext/Mesh.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/release/scripts/modules/bpy_ext/Object.py b/release/scripts/modules/bpy_ext/Object.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/release/scripts/modules/bpy_ext/__init__.py b/release/scripts/modules/bpy_ext/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
index 5a8b46c..6acff40 100644 (file)
 #
 # ##### END GPL LICENSE BLOCK #####
 
-import bpy
+from _bpy import types as bpy_types
 
-StructRNA = bpy.types.Struct.__bases__[0]
-# StructRNA = bpy.types.Struct
+StructRNA = bpy_types.Struct.__bases__[0]
+# StructRNA = bpy_types.Struct
 
 
 class Context(StructRNA):
@@ -34,7 +34,7 @@ class Context(StructRNA):
         return new_context
 
 
-class Object(bpy.types.ID):
+class Object(bpy_types.ID):
 
     def _get_children(self):
         return [child for child in bpy.data.objects if child.parent == self]
@@ -46,7 +46,7 @@ def ord_ind(i1,i2):
     if i1<i2: return i1,i2
     return i2,i1
 
-class Mesh(bpy.types.ID):
+class Mesh(bpy_types.ID):
     
     def _get_edge_keys(self):
         return [edge_key for face in self.faces for edge_key in face.edge_keys]
index df6f932..630ea75 100644 (file)
@@ -92,7 +92,7 @@ void SCRIPT_OT_python_file_run(wmOperatorType *ot)
 static int run_ui_scripts_exec(bContext *C, wmOperator *op)
 {
 #ifndef DISABLE_PYTHON
-       BPY_run_ui_scripts(C, 1); /* reload */
+//     TODO
 #endif
        return OPERATOR_FINISHED;
 }
index e73dec0..580d39b 100644 (file)
@@ -84,7 +84,6 @@ extern "C" {
        
        void BPY_start_python( int argc, char **argv );
        void BPY_end_python( void );
-       void BPY_post_start_python( void );
        void init_syspath( int first_time );
        void syspath_append( char *dir );
        void BPY_rebuild_syspath( void );
@@ -101,7 +100,6 @@ extern "C" {
        /* 2.5 UI Scripts */
        int BPY_run_python_script( struct bContext *C, const char *filename, struct Text *text, struct ReportList *reports ); // 2.5 working
        int BPY_run_script_space_draw(const struct bContext *C, struct SpaceScript * sc); // 2.5 working
-       void BPY_run_ui_scripts(struct bContext *C, int reload);
 //     int BPY_run_script_space_listener(struct bContext *C, struct SpaceScript * sc, struct ARegion *ar, struct wmNotifier *wmn); // 2.5 working
        void BPY_update_modules( void ); // XXX - annoying, need this for pointers that get out of date
        
@@ -137,7 +135,7 @@ extern "C" {
        
        void error_pyscript( void );
        void BPY_DECREF(void *pyob_ptr);        /* Py_DECREF() */
-
+       void BPY_set_context(struct bContext *C);
 /* void BPY_Err_Handle(struct Text *text); */
 /* int BPY_spacetext_is_pywin(struct SpaceText *st); */
 
index 47505f4..1eb48b1 100644 (file)
@@ -186,10 +186,10 @@ static void bpy_init_modules( void )
                Py_DECREF(py_modpath);
        }
        
-       mod = PyModule_New("bpy");
+       mod = PyModule_New("_bpy");
 
        /* add the module so we can import it */
-       PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod);
+       PyDict_SetItemString(PySys_GetObject("modules"), "_bpy", mod);
        Py_DECREF(mod);
 
        /* run first, initializes rna types */
@@ -201,7 +201,7 @@ static void bpy_init_modules( void )
        bpy_import_test("bpy_types");
        /* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
        PyModule_AddObject( mod, "props", BPY_rna_props() );
-       PyModule_AddObject( mod, "__ops__", BPY_operator_module() ); /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
+       PyModule_AddObject( mod, "ops", BPY_operator_module() ); /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
        PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experimental, consider this a test, especially PyCObject is not meant to be permanent
 
 
@@ -219,11 +219,8 @@ static void bpy_init_modules( void )
        Mathutils_Init();
        BGL_Init();
 
-       /* add our own modules dir */
-       {
-               bpy_import_test("bpy_ops"); /* adds its self to bpy.ops */
-               bpy_import_test("bpy_utils"); /* adds its self to bpy.sys */
-       }
+       /* add our own modules dir, this is a python package */
+       bpy_import_test("bpy");
 }
 
 void BPY_update_modules( void )
@@ -303,6 +300,13 @@ void BPY_start_python_path(void)
 }
 
 
+
+void BPY_set_context(bContext *C)
+{
+       BPy_SetContext(C);
+}
+
+/* call BPY_set_context first */
 void BPY_start_python( int argc, char **argv )
 {
        PyThreadState *py_tstate = NULL;
@@ -600,117 +604,6 @@ int BPY_run_python_script_space(const char *modulename, const char *func)
 #include "PIL_time.h"
 #endif
 
-/* for use by BPY_run_ui_scripts only */
-static int bpy_import_module(char *modname, int reload)
-{
-       PyObject *mod= PyImport_ImportModuleLevel(modname, 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 */
-               return 0;
-       } else {
-               return -1;
-       }
-}
-
-/* XXX this is temporary, need a proper script registration system for 2.5 */
-void BPY_run_ui_scripts(bContext *C, int reload)
-{
-#ifdef TIME_REGISTRATION
-       double time = PIL_check_seconds_timer();
-#endif
-       DIR *dir; 
-       struct dirent *de;
-       char *file_extension;
-       char *dirname;
-       char path[FILE_MAX];
-       char *dirs[] = {"scripts/ui", "scripts/op", "scripts/io", NULL};
-       int path_flags[] = {BLI_GETHOME_LOCAL|BLI_GETHOME_SYSTEM, BLI_GETHOME_USER}; /* SYSTEM / NON-SYSTEM */
-       int a, err, flag_iter;
-       
-       PyGILState_STATE gilstate;
-       PyObject *sys_path;
-
-       bpy_context_set(C, &gilstate);
-
-       sys_path= PySys_GetObject("path"); /* borrow */
-       PyList_Insert(sys_path, 0, Py_None); /* place holder, resizes the list */
-
-       /* Scan system scripts first, then local/user */
-       for(flag_iter=0; flag_iter < sizeof(path_flags)/sizeof(int); flag_iter++) {
-               
-               for(a=0; dirs[a]; a++) {
-                       dirname= BLI_gethome_folder(dirs[a], path_flags[flag_iter]);
-
-                       if(!dirname)
-                               continue;
-
-                       dir = opendir(dirname);
-
-                       if(!dir)
-                               continue;
-                       
-                       /* set the first dir in the sys.path for fast importing of modules */
-                       PyList_SetItem(sys_path, 0, PyUnicode_FromString(dirname)); /* steals the ref */
-                               
-                       while((de = readdir(dir)) != NULL) {
-                               /* We could stat the file but easier just to let python
-                                * import it and complain if theres a problem */
-                               err = 0;
-
-                               if (de->d_name[0] == '.') {
-                                       /* do nothing, probably .svn */
-                               }
-                               else if ((file_extension = strstr(de->d_name, ".py"))) {
-                                       /* normal py files? */
-                                       if(file_extension && file_extension[3] == '\0') {
-                                               de->d_name[(file_extension - de->d_name)] = '\0';
-                                               err= bpy_import_module(de->d_name, reload);
-                                       }
-                               }
-#ifndef __linux__
-                               else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exist(path))) {
-#else
-                               else if(de->d_type==DT_DIR) {
-                                       BLI_join_dirfile(path, dirname, de->d_name);
-#endif
-                                       /* support packages */
-                                       BLI_join_dirfile(path, path, "__init__.py");
-
-                                       if(BLI_exists(path)) {
-                                               err= bpy_import_module(de->d_name, reload);
-                                       }
-                               }
-
-                               if(err==-1) {
-                                       BPy_errors_to_report(NULL);
-                                       fprintf(stderr, "unable to import %s/%s\n", dirname, de->d_name);
-                               }
-                       }
-
-                       closedir(dir);
-               }
-       }
-       
-       PyList_SetSlice(sys_path, 0, 1, NULL); /* remove the first item */
-
-       bpy_context_clear(C, &gilstate);
-       
-#ifdef TIME_REGISTRATION
-       printf("script time %f\n", (PIL_check_seconds_timer()-time));
-#endif
-
-       /* reset the timer so as not to take loading into the stats */
-       bpy_timer_count = 0;
-}
-
 /* ****************************************** */
 /* Drivers - PyExpression Evaluation */
 
index 94bdb6b..303fd84 100644 (file)
@@ -27,7 +27,6 @@
  */
 
 /* python, will come back */
-void BPY_post_start_python() {}
 //void BPY_run_python_script() {}
 //void BPY_start_python() {}
 void BPY_call_importloader() {}
index b4c962c..6535f57 100644 (file)
@@ -489,11 +489,12 @@ int main(int argc, char **argv)
                        }
                }
 
-#ifndef DISABLE_PYTHON         
-               BPY_start_python(argc, argv);
-#endif         
-
                WM_init(C);
+
+#ifndef DISABLE_PYTHON
+               BPY_set_context(C); /* necessary evil */
+               BPY_start_python(argc, argv);
+#endif
                
                // XXX BRECHT SOLVE
                BLI_where_is_temp( btempdir, 1 ); /* call after loading the .B.blend so we can read U.tempdir */
@@ -530,6 +531,7 @@ int main(int argc, char **argv)
                WM_init(C);
 
 #ifndef DISABLE_PYTHON
+               BPY_set_context(C); /* necessary evil */
                BPY_start_python(argc, argv);
 #endif         
                BLI_where_is_temp( btempdir, 0 ); /* call after loading the .B.blend so we can read U.tempdir */
@@ -543,13 +545,13 @@ int main(int argc, char **argv)
         * Update: now this function also inits the bpymenus, which also depend
         * on U.pythondir.
         */
-       BPY_post_start_python();
+       
+       // TODO - U.pythondir
 
-       BPY_run_ui_scripts(C, 0); /* dont need to reload the first time */
 #endif
        
        CTX_py_init_set(C, 1);
-       WM_keymap_init(C); /* after BPY_run_ui_scripts() */
+       WM_keymap_init(C);
 
 #ifdef WITH_QUICKTIME