forked from bartvdbraak/blender
- 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
This commit is contained in:
parent
a668915404
commit
1658a28a58
@ -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
|
||||
|
||||
|
||||
|
@ -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'}
|
||||
|
@ -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*/
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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])
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
/* 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);
|
||||
|
||||
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?
|
||||
}
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user