changes python initialization

- 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.
This commit is contained in:
2009-11-13 09:28:05 +00:00
parent d0dff582a8
commit 4c7dc3e5c5
13 changed files with 96 additions and 154 deletions

View File

@@ -18,15 +18,15 @@
# 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

View File

@@ -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)

View File

@@ -19,12 +19,14 @@
# <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()

View File

@@ -25,6 +25,3 @@ def expandpath(path):
return path
import types
bpy.utils = types.ModuleType("bpy.utils")
bpy.utils.expandpath = expandpath

View File

@@ -16,10 +16,10 @@
#
# ##### 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]

View 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;
}

View 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); */

View 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 */

View 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() {}

View File

@@ -489,12 +489,13 @@ int main(int argc, char **argv)
}
}
WM_init(C);
#ifndef DISABLE_PYTHON
BPY_set_context(C); /* necessary evil */
BPY_start_python(argc, argv);
#endif
WM_init(C);
// 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();
BPY_run_ui_scripts(C, 0); /* dont need to reload the first time */
// TODO - U.pythondir
#endif
CTX_py_init_set(C, 1);
WM_keymap_init(C); /* after BPY_run_ui_scripts() */
WM_keymap_init(C);
#ifdef WITH_QUICKTIME