diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-05-30 18:05:58 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-05-30 18:05:58 +0400 |
commit | 1658a28a58ebd5fe58ab33875b10aaabb3458b79 (patch) | |
tree | 336b92b490fd408daaead6acb4508ead119ca676 | |
parent | a6689154047b4a838276170f48bd39372149af71 (diff) |
- Python console argument '--python-console', option so you can start blender and drop into a python console, (useful for debugging some problems on a renderfarm over ssh)
- Also made it so sys.stdin isnt overwritten anymore, instead the interactive consoel overwrites while it executes and restores after.
- removed hope folder from sphinx patch path
-rw-r--r-- | release/scripts/modules/bpy/__init__.py | 8 | ||||
-rw-r--r-- | release/scripts/op/console_python.py | 15 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fmodifier.c | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 2 | ||||
-rw-r--r-- | source/blender/python/BPY_extern.h | 6 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_driver.c | 10 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_interface.c | 36 | ||||
-rw-r--r-- | source/creator/creator.c | 65 |
9 files changed, 106 insertions, 40 deletions
diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py index f0025290f09..1e6db441599 100644 --- a/release/scripts/modules/bpy/__init__.py +++ b/release/scripts/modules/bpy/__init__.py @@ -43,17 +43,11 @@ def _main(): ## people need to explain how this is even a fix. # _sys.path[:] = filter(None, _sys.path) - # a bit nasty but this prevents help() and input() from locking blender - # Ideally we could have some way for the console to replace sys.stdin but - # python would lock blender while waiting for a return value, not easy :| - - if not app.debug: - _sys.stdin = None - # because of how the console works. we need our own help() pager func. # replace the bold function because it adds crazy chars import pydoc pydoc.getpager = lambda: pydoc.plainpager + pydoc.Helper.getline = lambda self, prompt: None pydoc.TextDoc.bold = lambda self, text: text diff --git a/release/scripts/op/console_python.py b/release/scripts/op/console_python.py index 87abe0b6f47..e2b046aae8c 100644 --- a/release/scripts/op/console_python.py +++ b/release/scripts/op/console_python.py @@ -102,6 +102,10 @@ def execute(context): sys.stdout = stdout sys.stderr = stderr + # dont allow the stdin to be used, can lock blender. + stdin_backup = sys.stdin + sys.stdin = None + # run the console if not line.strip(): line_exec = '\n' # executes a multiline statement @@ -144,6 +148,9 @@ def execute(context): if output_err: add_scrollback(output_err, 'ERROR') + # restore the stdin + sys.stdin = stdin_backup + return {'FINISHED'} @@ -163,6 +170,11 @@ def autocomplete(context): if sc.console_type != 'PYTHON': return {'CANCELLED'} + # dont allow the stdin to be used, can lock blender. + # note: unlikely stdin would be used for autocomp. but its possible. + stdin_backup = sys.stdin + sys.stdin = None + # This function isnt aware of the text editor or being an operator # just does the autocomp then copy its results back current_line.line, current_line.current_character, scrollback = \ @@ -182,6 +194,9 @@ def autocomplete(context): if scrollback: add_scrollback(scrollback, 'INFO') + # restore the stdin + sys.stdin = stdin_backup + context.area.tag_redraw() return {'FINISHED'} diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 619bb1a58f9..43f01199b69 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1418,7 +1418,7 @@ static float evaluate_driver (ChannelDriver *driver, float evaltime) /* this evaluates the expression using Python,and returns its result: * - on errors it reports, then returns 0.0f */ - driver->curval= BPY_pydriver_eval(driver); + driver->curval= BPY_eval_driver(driver); } #endif /* DISABLE_PYTHON*/ } diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 868b06f2348..6fcc49f9ec1 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -44,7 +44,7 @@ #include "BKE_utildefines.h" #ifndef DISABLE_PYTHON -#include "BPY_extern.h" /* for BPY_pydriver_eval() */ +#include "BPY_extern.h" /* for BPY_eval_driver() */ #endif #define SMALL -1.0e-10 diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 7f8d6e8e3cb..3f0cd3bee78 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1633,7 +1633,7 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str) bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), but->drawstr, ui_get_but_scale_unit(but, 1.0), scene->unit.system, unit_type); } - if(BPY_button_eval(C, str_unit_convert, &value)) { + if(BPY_eval_button(C, str_unit_convert, &value)) { value = ui_get_but_val(but); /* use its original value */ if(str[0]) diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index 11208d54a73..40d544ac17e 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -119,9 +119,11 @@ extern "C" { // short eventValue, unsigned short space_event); // // void BPY_pydriver_update(void); - float BPY_pydriver_eval(struct ChannelDriver *driver); + float BPY_eval_driver(struct ChannelDriver *driver); // - int BPY_button_eval(struct bContext *C, char *expr, double *value); + int BPY_eval_button(struct bContext *C, const char *expr, double *value); + + int BPY_eval_string(struct bContext *C, const char *expr); /* format importer hook */ int BPY_call_importloader( char *name ); diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index afe6b63458f..8f49263b375 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -103,7 +103,7 @@ static int bpy_pydriver_create_dict(void) } /* Update function, it gets rid of pydrivers global dictionary, forcing - * BPY_pydriver_eval to recreate it. This function is used to force + * BPY_eval_driver to recreate it. This function is used to force * reloading the Blender text module "pydrivers.py", if available, so * updates in it reach pydriver evaluation. */ @@ -153,7 +153,7 @@ static float pydriver_error(ChannelDriver *driver) * bake operator which intern starts a thread which calls scene update which * does a driver update. to avoid a deadlock check PyThreadState_Get() if PyGILState_Ensure() is needed. */ -float BPY_pydriver_eval (ChannelDriver *driver) +float BPY_eval_driver (ChannelDriver *driver) { PyObject *driver_vars=NULL; PyObject *retval= NULL; @@ -246,11 +246,11 @@ float BPY_pydriver_eval (ChannelDriver *driver) /* this target failed - bad name */ if (targets_ok) { /* first one - print some extra info for easier identification */ - fprintf(stderr, "\nBPY_pydriver_eval() - Error while evaluating PyDriver:\n"); + fprintf(stderr, "\nBPY_eval_driver() - Error while evaluating PyDriver:\n"); targets_ok= 0; } - fprintf(stderr, "\tBPY_pydriver_eval() - couldn't add variable '%s' to namespace\n", dvar->name); + fprintf(stderr, "\tBPY_eval_driver() - couldn't add variable '%s' to namespace\n", dvar->name); // BPy_errors_to_report(NULL); // TODO - reports PyErr_Print(); PyErr_Clear(); @@ -290,7 +290,7 @@ float BPY_pydriver_eval (ChannelDriver *driver) return (float)result; } else { - fprintf(stderr, "\tBPY_pydriver_eval() - driver '%s' evaluates to '%f'\n", dvar->name, result); + fprintf(stderr, "\tBPY_eval_driver() - driver '%s' evaluates to '%f'\n", dvar->name, result); return 0.0f; } } diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 285dbb78874..2a3f83a066b 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -528,7 +528,7 @@ int BPY_run_python_script_space(const char *modulename, const char *func) #endif -int BPY_button_eval(bContext *C, char *expr, double *value) +int BPY_eval_button(bContext *C, const char *expr, double *value) { PyGILState_STATE gilstate; PyObject *dict, *mod, *retval; @@ -599,6 +599,40 @@ int BPY_button_eval(bContext *C, char *expr, double *value) return error_ret; } +int BPY_eval_string(bContext *C, const char *expr) +{ + PyGILState_STATE gilstate; + PyObject *dict, *retval; + int error_ret = 0; + + if (!expr) return -1; + + if(expr[0]=='\0') { + return error_ret; + } + + bpy_context_set(C, &gilstate); + + dict= CreateGlobalDictionary(C, NULL); + + retval = PyRun_String(expr, Py_eval_input, dict, dict); + + if (retval == NULL) { + error_ret= -1; + + BPy_errors_to_report(CTX_wm_reports(C)); + } + else { + Py_DECREF(retval); + } + + Py_DECREF(dict); + bpy_context_clear(C, &gilstate); + + return error_ret; +} + + void BPY_load_user_modules(bContext *C) { PyGILState_STATE gilstate; diff --git a/source/creator/creator.c b/source/creator/creator.c index 7a8d7d32d9b..2c48aa9a885 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -261,6 +261,7 @@ static int print_help(int argc, char **argv, void *data) printf("\n"); BLI_argsPrintArgDoc(ba, "--python"); + BLI_argsPrintArgDoc(ba, "--python-console"); #ifdef WIN32 BLI_argsPrintArgDoc(ba, "-R"); @@ -789,36 +790,40 @@ static int set_skip_frame(int argc, char **argv, void *data) } } +/* macro for ugly context setup/reset */ +#ifndef DISABLE_PYTHON +#define BPY_CTX_SETUP(_cmd) \ +{ \ + wmWindowManager *wm= CTX_wm_manager(C); \ + wmWindow *prevwin= CTX_wm_window(C); \ + Scene *prevscene= CTX_data_scene(C); \ + if(wm->windows.first) { \ + CTX_wm_window_set(C, wm->windows.first); \ + _cmd; \ + CTX_wm_window_set(C, prevwin); \ + } \ + else { \ + fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \ + _cmd; \ + } \ + CTX_data_scene_set(C, prevscene); \ +} \ + +#endif /* DISABLE_PYTHON */ + static int run_python(int argc, char **argv, void *data) { #ifndef DISABLE_PYTHON bContext *C = data; - /* Make the path absolute because its needed for relative linked blends to be found */ - char filename[FILE_MAXDIR + FILE_MAXFILE]; - BLI_strncpy(filename, argv[1], sizeof(filename)); - BLI_path_cwd(filename); - /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */ if (argc > 1) { - /* XXX, temp setting the WM is ugly, splash also does this :S */ - wmWindowManager *wm= CTX_wm_manager(C); - wmWindow *prevwin= CTX_wm_window(C); - Scene *prevscene= CTX_data_scene(C); - - if(wm->windows.first) { - CTX_wm_window_set(C, wm->windows.first); - - BPY_run_python_script(C, filename, NULL, NULL); // use reports? - - CTX_wm_window_set(C, prevwin); - } - else { - fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); - BPY_run_python_script(C, filename, NULL, NULL); // use reports? - } + /* Make the path absolute because its needed for relative linked blends to be found */ + char filename[FILE_MAXDIR + FILE_MAXFILE]; + BLI_strncpy(filename, argv[1], sizeof(filename)); + BLI_path_cwd(filename); - CTX_data_scene_set(C, prevscene); + BPY_CTX_SETUP( BPY_run_python_script(C, filename, NULL, NULL) ) return 1; } else { @@ -831,6 +836,21 @@ static int run_python(int argc, char **argv, void *data) #endif /* DISABLE_PYTHON */ } +static int run_python_console(int argc, char **argv, void *data) +{ +#ifndef DISABLE_PYTHON + bContext *C = data; + const char *expr= "__import__('code').interact()"; + + BPY_CTX_SETUP( BPY_eval_string(C, expr) ) + + return 0; +#else + printf("This blender was built without python support\n"); + return 0; +#endif /* DISABLE_PYTHON */ +} + static int load_file(int argc, char **argv, void *data) { bContext *C = data; @@ -955,6 +975,7 @@ void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C); BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C); BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C); + BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C); BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C); BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C); |