Cleanup: move Python script execution into BPY_extern_run.h
This commit renames 'execute' to 'run' because: - This follows Python's "PyRun" which these functions wrap. - Execution functions can use either exec/eval modes, making naming awkward (for future API refactoring).
This commit is contained in:
@@ -69,7 +69,9 @@
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "BPY_extern.h"
|
||||
#ifdef WITH_PYTHON
|
||||
# include "BPY_extern_run.h"
|
||||
#endif
|
||||
|
||||
#include "ED_numinput.h"
|
||||
#include "ED_screen.h"
|
||||
@@ -2812,7 +2814,7 @@ char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size)
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a generic error prefix when evaluating a string with #BPY_execute_string_as_number
|
||||
* Report a generic error prefix when evaluating a string with #BPY_run_string_as_number
|
||||
* as the Python error on it's own doesn't provide enough context.
|
||||
*/
|
||||
#define UI_NUMBER_EVAL_ERROR_PREFIX IFACE_("Error evaluating number, see Info editor for details")
|
||||
@@ -2837,7 +2839,7 @@ static bool ui_number_from_string(bContext *C, const char *str, double *r_value)
|
||||
{
|
||||
bool ok;
|
||||
#ifdef WITH_PYTHON
|
||||
ok = BPY_execute_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value);
|
||||
ok = BPY_run_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value);
|
||||
#else
|
||||
UNUSED_VARS(C);
|
||||
*r_value = atof(str);
|
||||
|
@@ -47,7 +47,10 @@
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "BPY_extern.h"
|
||||
#ifdef WITH_PYTHON
|
||||
# include "BPY_extern.h"
|
||||
# include "BPY_extern_run.h"
|
||||
#endif
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@@ -407,7 +410,7 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
|
||||
"'%s').label",
|
||||
idname);
|
||||
char *expr_result = NULL;
|
||||
if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
|
||||
if (BPY_run_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
|
||||
STRNCPY(drawstr, expr_result);
|
||||
MEM_freeN(expr_result);
|
||||
}
|
||||
|
@@ -63,7 +63,7 @@
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
# include "BPY_extern.h"
|
||||
# include "BPY_extern_run.h"
|
||||
#endif
|
||||
|
||||
#include "ED_screen.h"
|
||||
@@ -433,7 +433,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
|
||||
if (has_valid_context == false) {
|
||||
expr_result = BLI_strdup(has_valid_context_error);
|
||||
}
|
||||
else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
|
||||
else if (BPY_run_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
|
||||
if (STREQ(expr_result, "")) {
|
||||
MEM_freeN(expr_result);
|
||||
expr_result = NULL;
|
||||
@@ -490,7 +490,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
|
||||
if (has_valid_context == false) {
|
||||
expr_result = BLI_strdup(has_valid_context_error);
|
||||
}
|
||||
else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
|
||||
else if (BPY_run_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
|
||||
if (STREQ(expr_result, ".")) {
|
||||
MEM_freeN(expr_result);
|
||||
expr_result = NULL;
|
||||
@@ -594,7 +594,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
|
||||
if (has_valid_context == false) {
|
||||
shortcut = BLI_strdup(has_valid_context_error);
|
||||
}
|
||||
else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
|
||||
else if (BPY_run_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
|
||||
if (expr_result != 0) {
|
||||
wmKeyMap *keymap = (wmKeyMap *)expr_result;
|
||||
LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
|
||||
@@ -658,7 +658,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
|
||||
if (has_valid_context == false) {
|
||||
/* pass */
|
||||
}
|
||||
else if (BPY_execute_string_as_string_and_size(
|
||||
else if (BPY_run_string_as_string_and_size(
|
||||
C, expr_imports, expr, __func__, &expr_result, &expr_result_len)) {
|
||||
/* pass. */
|
||||
}
|
||||
@@ -736,7 +736,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
|
||||
if (has_valid_context == false) {
|
||||
/* pass */
|
||||
}
|
||||
else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
|
||||
else if (BPY_run_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
|
||||
if (expr_result != 0) {
|
||||
{
|
||||
uiTooltipField *field = text_field_add(data,
|
||||
|
@@ -42,7 +42,7 @@
|
||||
#include "script_intern.h" // own include
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
# include "BPY_extern.h" /* BPY_script_exec */
|
||||
# include "BPY_extern_run.h"
|
||||
#endif
|
||||
|
||||
static int run_pyfile_exec(bContext *C, wmOperator *op)
|
||||
@@ -50,7 +50,7 @@ static int run_pyfile_exec(bContext *C, wmOperator *op)
|
||||
char path[512];
|
||||
RNA_string_get(op->ptr, "filepath", path);
|
||||
#ifdef WITH_PYTHON
|
||||
if (BPY_execute_filepath(C, path, op->reports)) {
|
||||
if (BPY_run_filepath(C, path, op->reports)) {
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
ED_region_tag_redraw(region);
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -120,8 +120,7 @@ static int script_reload_exec(bContext *C, wmOperator *op)
|
||||
/* TODO, this crashes on netrender and keying sets, need to look into why
|
||||
* disable for now unless running in debug mode */
|
||||
WM_cursor_wait(1);
|
||||
BPY_execute_string(
|
||||
C, (const char *[]){"bpy", NULL}, "bpy.utils.load_scripts(reload_scripts=True)");
|
||||
BPY_run_string(C, (const char *[]){"bpy", NULL}, "bpy.utils.load_scripts(reload_scripts=True)");
|
||||
WM_cursor_wait(0);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
return OPERATOR_FINISHED;
|
||||
|
@@ -55,6 +55,7 @@
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
# include "BPY_extern.h"
|
||||
# include "BPY_extern_run.h"
|
||||
#endif
|
||||
|
||||
#include "text_format.h"
|
||||
@@ -756,7 +757,7 @@ static int text_run_script(bContext *C, ReportList *reports)
|
||||
void *curl_prev = text->curl;
|
||||
int curc_prev = text->curc;
|
||||
|
||||
if (BPY_execute_text(C, text, reports, !is_live)) {
|
||||
if (BPY_run_text(C, text, reports, !is_live)) {
|
||||
if (is_live) {
|
||||
/* for nice live updates */
|
||||
WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);
|
||||
|
@@ -38,7 +38,7 @@
|
||||
#include "WM_types.h"
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
# include "BPY_extern.h"
|
||||
# include "BPY_extern_run.h"
|
||||
#endif
|
||||
|
||||
#include "ED_numinput.h"
|
||||
@@ -294,10 +294,10 @@ bool user_string_to_number(bContext *C,
|
||||
bUnit_ReplaceString(
|
||||
str_unit_convert, sizeof(str_unit_convert), str, unit_scale, unit->system, type);
|
||||
|
||||
return BPY_execute_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value);
|
||||
return BPY_run_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value);
|
||||
}
|
||||
|
||||
int success = BPY_execute_string_as_number(C, NULL, str, error_prefix, r_value);
|
||||
int success = BPY_run_string_as_number(C, NULL, str, error_prefix, r_value);
|
||||
*r_value *= bUnit_PreferredInputUnitScalar(unit, type);
|
||||
*r_value /= unit_scale;
|
||||
return success;
|
||||
|
@@ -42,7 +42,7 @@ extern "C" {
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_text.h"
|
||||
|
||||
#include "BPY_extern.h"
|
||||
#include "BPY_extern_run.h"
|
||||
|
||||
#include "bpy_capi_utils.h"
|
||||
|
||||
@@ -68,12 +68,12 @@ class PythonInterpreter : public Interpreter {
|
||||
BKE_reports_clear(reports);
|
||||
char *fn = const_cast<char *>(filename.c_str());
|
||||
#if 0
|
||||
bool ok = BPY_execute_filepath(_context, fn, reports);
|
||||
bool ok = BPY_run_filepath(_context, fn, reports);
|
||||
#else
|
||||
bool ok;
|
||||
Text *text = BKE_text_load(&_freestyle_bmain, fn, G_MAIN->name);
|
||||
if (text) {
|
||||
ok = BPY_execute_text(_context, text, reports, false);
|
||||
ok = BPY_run_text(_context, text, reports, false);
|
||||
BKE_id_delete(&_freestyle_bmain, text);
|
||||
}
|
||||
else {
|
||||
@@ -102,7 +102,7 @@ class PythonInterpreter : public Interpreter {
|
||||
|
||||
BKE_reports_clear(reports);
|
||||
|
||||
if (!BPY_execute_string(_context, NULL, str.c_str())) {
|
||||
if (!BPY_run_string(_context, NULL, str.c_str())) {
|
||||
BPy_errors_to_report(reports);
|
||||
cerr << "\nError executing Python script from PythonInterpreter::interpretString" << endl;
|
||||
cerr << "Name: " << name << endl;
|
||||
@@ -122,7 +122,7 @@ class PythonInterpreter : public Interpreter {
|
||||
|
||||
BKE_reports_clear(reports);
|
||||
|
||||
if (!BPY_execute_text(_context, text, reports, false)) {
|
||||
if (!BPY_run_text(_context, text, reports, false)) {
|
||||
cerr << "\nError executing Python script from PythonInterpreter::interpretText" << endl;
|
||||
cerr << "Name: " << name << endl;
|
||||
cerr << "Errors: " << endl;
|
||||
|
@@ -67,40 +67,6 @@ void BPY_thread_restore(BPy_ThreadStatePtr tstate);
|
||||
} \
|
||||
(void)0
|
||||
|
||||
bool BPY_execute_filepath(struct bContext *C, const char *filepath, struct ReportList *reports);
|
||||
bool BPY_execute_text(struct bContext *C,
|
||||
struct Text *text,
|
||||
struct ReportList *reports,
|
||||
const bool do_jump);
|
||||
|
||||
bool BPY_execute_string_as_number(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
double *r_value);
|
||||
bool BPY_execute_string_as_intptr(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
intptr_t *r_value);
|
||||
bool BPY_execute_string_as_string_and_size(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
char **r_value,
|
||||
size_t *r_value_size);
|
||||
bool BPY_execute_string_as_string(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
char **r_value);
|
||||
|
||||
bool BPY_execute_string_ex(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
bool use_eval);
|
||||
bool BPY_execute_string(struct bContext *C, const char *imports[], const char *expr);
|
||||
|
||||
void BPY_text_free_code(struct Text *text);
|
||||
void BPY_modules_update(
|
||||
struct bContext *C); // XXX - annoying, need this for pointers that get out of date
|
||||
|
68
source/blender/python/BPY_extern_run.h
Normal file
68
source/blender/python/BPY_extern_run.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup python
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
struct ReportList;
|
||||
struct Text;
|
||||
struct bContext;
|
||||
|
||||
/* bpy_interface_run.c */
|
||||
bool BPY_run_filepath(struct bContext *C, const char *filepath, struct ReportList *reports);
|
||||
bool BPY_run_text(struct bContext *C,
|
||||
struct Text *text,
|
||||
struct ReportList *reports,
|
||||
const bool do_jump);
|
||||
|
||||
bool BPY_run_string_as_number(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
double *r_value);
|
||||
bool BPY_run_string_as_intptr(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
intptr_t *r_value);
|
||||
bool BPY_run_string_as_string_and_size(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
char **r_value,
|
||||
size_t *r_value_size);
|
||||
bool BPY_run_string_as_string(struct bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
char **r_value);
|
||||
|
||||
bool BPY_run_string_ex(struct bContext *C, const char *imports[], const char *expr, bool use_eval);
|
||||
|
||||
bool BPY_run_string(struct bContext *C, const char *imports[], const char *expr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
@@ -62,6 +62,7 @@ set(SRC
|
||||
bpy_gizmo_wrap.c
|
||||
bpy_interface.c
|
||||
bpy_interface_atexit.c
|
||||
bpy_interface_run.c
|
||||
bpy_intern_string.c
|
||||
bpy_library_load.c
|
||||
bpy_library_write.c
|
||||
|
@@ -64,6 +64,7 @@
|
||||
|
||||
#include "BPY_extern.h"
|
||||
#include "BPY_extern_python.h"
|
||||
#include "BPY_extern_run.h"
|
||||
|
||||
#include "../generic/py_capi_utils.h"
|
||||
|
||||
@@ -428,18 +429,6 @@ void BPY_python_use_system_env(void)
|
||||
py_use_system_env = true;
|
||||
}
|
||||
|
||||
static void python_script_error_jump_text(struct Text *text)
|
||||
{
|
||||
int lineno;
|
||||
int offset;
|
||||
python_script_error_jump(text->id.name + 2, &lineno, &offset);
|
||||
if (lineno != -1) {
|
||||
/* select the line with the error */
|
||||
txt_move_to(text, lineno - 1, INT_MAX, false);
|
||||
txt_move_to(text, lineno - 1, offset, true);
|
||||
}
|
||||
}
|
||||
|
||||
void BPY_python_backtrace(FILE *fp)
|
||||
{
|
||||
fputs("\n# Python backtrace\n", fp);
|
||||
@@ -467,152 +456,6 @@ typedef struct {
|
||||
} PyModuleObject;
|
||||
#endif
|
||||
|
||||
/* returns a dummy filename for a textblock so we can tell what file a text block comes from */
|
||||
static void bpy_text_filename_get(char *fn, const Main *bmain, size_t fn_len, const Text *text)
|
||||
{
|
||||
BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bmain, &text->id), SEP, text->id.name + 2);
|
||||
}
|
||||
|
||||
static bool python_script_exec(
|
||||
bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const bool do_jump)
|
||||
{
|
||||
Main *bmain_old = CTX_data_main(C);
|
||||
PyObject *main_mod = NULL;
|
||||
PyObject *py_dict = NULL, *py_result = NULL;
|
||||
PyGILState_STATE gilstate;
|
||||
|
||||
BLI_assert(fn || text);
|
||||
|
||||
if (fn == NULL && text == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
PyC_MainModule_Backup(&main_mod);
|
||||
|
||||
if (text) {
|
||||
char fn_dummy[FILE_MAXDIR];
|
||||
bpy_text_filename_get(fn_dummy, bmain_old, sizeof(fn_dummy), text);
|
||||
|
||||
if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */
|
||||
char *buf;
|
||||
PyObject *fn_dummy_py;
|
||||
|
||||
fn_dummy_py = PyC_UnicodeFromByte(fn_dummy);
|
||||
|
||||
buf = txt_to_buf(text, NULL);
|
||||
text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1);
|
||||
MEM_freeN(buf);
|
||||
|
||||
Py_DECREF(fn_dummy_py);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
if (do_jump) {
|
||||
python_script_error_jump_text(text);
|
||||
}
|
||||
BPY_text_free_code(text);
|
||||
}
|
||||
}
|
||||
|
||||
if (text->compiled) {
|
||||
py_dict = PyC_DefaultNameSpace(fn_dummy);
|
||||
py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict);
|
||||
}
|
||||
}
|
||||
else {
|
||||
FILE *fp = BLI_fopen(fn, "r");
|
||||
|
||||
if (fp) {
|
||||
py_dict = PyC_DefaultNameSpace(fn);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Previously we used PyRun_File to run directly the code on a FILE
|
||||
* object, but as written in the Python/C API Ref Manual, chapter 2,
|
||||
* 'FILE structs for different C libraries can be different and
|
||||
* incompatible'.
|
||||
* So now we load the script file data to a buffer.
|
||||
*
|
||||
* Note on use of 'globals()', it's important not copy the dictionary because
|
||||
* tools may inspect 'sys.modules["__main__"]' for variables defined in the code
|
||||
* where using a copy of 'globals()' causes code execution
|
||||
* to leave the main namespace untouched. see: T51444
|
||||
*
|
||||
* This leaves us with the problem of variables being included,
|
||||
* currently this is worked around using 'dict.__del__' it's ugly but works.
|
||||
*/
|
||||
{
|
||||
const char *pystring =
|
||||
"with open(__file__, 'rb') as f:"
|
||||
"exec(compile(f.read(), __file__, 'exec'), globals().__delitem__('f') or globals())";
|
||||
|
||||
fclose(fp);
|
||||
|
||||
py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict);
|
||||
}
|
||||
#else
|
||||
py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
|
||||
fclose(fp);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
PyErr_Format(
|
||||
PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno));
|
||||
py_result = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!py_result) {
|
||||
if (text) {
|
||||
if (do_jump) {
|
||||
/* ensure text is valid before use, the script may have freed its self */
|
||||
Main *bmain_new = CTX_data_main(C);
|
||||
if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->texts, text) != -1)) {
|
||||
python_script_error_jump_text(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
BPy_errors_to_report(reports);
|
||||
}
|
||||
else {
|
||||
Py_DECREF(py_result);
|
||||
}
|
||||
|
||||
if (py_dict) {
|
||||
#ifdef PYMODULE_CLEAR_WORKAROUND
|
||||
PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItem(PyImport_GetModuleDict(),
|
||||
bpy_intern_str___main__);
|
||||
PyObject *dict_back = mmod->md_dict;
|
||||
/* freeing the module will clear the namespace,
|
||||
* gives problems running classes defined in this namespace being used later. */
|
||||
mmod->md_dict = NULL;
|
||||
Py_DECREF(dict_back);
|
||||
#endif
|
||||
|
||||
#undef PYMODULE_CLEAR_WORKAROUND
|
||||
}
|
||||
|
||||
PyC_MainModule_Restore(main_mod);
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return (py_result != NULL);
|
||||
}
|
||||
|
||||
/* Can run a file or text block */
|
||||
bool BPY_execute_filepath(bContext *C, const char *filepath, struct ReportList *reports)
|
||||
{
|
||||
return python_script_exec(C, filepath, NULL, reports, false);
|
||||
}
|
||||
|
||||
bool BPY_execute_text(bContext *C,
|
||||
struct Text *text,
|
||||
struct ReportList *reports,
|
||||
const bool do_jump)
|
||||
{
|
||||
return python_script_exec(C, NULL, text, reports, do_jump);
|
||||
}
|
||||
|
||||
void BPY_DECREF(void *pyob_ptr)
|
||||
{
|
||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||
@@ -631,177 +474,6 @@ void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
|
||||
/**
|
||||
* \return success
|
||||
*/
|
||||
bool BPY_execute_string_as_number(bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
double *r_value)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
bool ok = true;
|
||||
|
||||
if (!r_value || !expr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (expr[0] == '\0') {
|
||||
*r_value = 0.0;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
ok = PyC_RunString_AsNumber(imports, expr, "<expr as number>", r_value);
|
||||
|
||||
if (ok == false) {
|
||||
if (report_prefix != NULL) {
|
||||
BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* \return success
|
||||
*/
|
||||
bool BPY_execute_string_as_string_and_size(bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
char **r_value,
|
||||
size_t *r_value_size)
|
||||
{
|
||||
BLI_assert(r_value && expr);
|
||||
PyGILState_STATE gilstate;
|
||||
bool ok = true;
|
||||
|
||||
if (expr[0] == '\0') {
|
||||
*r_value = NULL;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
ok = PyC_RunString_AsStringAndSize(imports, expr, "<expr as str>", r_value, r_value_size);
|
||||
|
||||
if (ok == false) {
|
||||
if (report_prefix != NULL) {
|
||||
BPy_errors_to_report_ex(CTX_wm_reports(C), false, false, report_prefix);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool BPY_execute_string_as_string(bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
char **r_value)
|
||||
{
|
||||
size_t value_dummy_size;
|
||||
return BPY_execute_string_as_string_and_size(
|
||||
C, imports, expr, report_prefix, r_value, &value_dummy_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Support both int and pointers.
|
||||
*
|
||||
* \return success
|
||||
*/
|
||||
bool BPY_execute_string_as_intptr(bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
intptr_t *r_value)
|
||||
{
|
||||
BLI_assert(r_value && expr);
|
||||
PyGILState_STATE gilstate;
|
||||
bool ok = true;
|
||||
|
||||
if (expr[0] == '\0') {
|
||||
*r_value = 0;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
ok = PyC_RunString_AsIntPtr(imports, expr, "<expr as intptr>", r_value);
|
||||
|
||||
if (ok == false) {
|
||||
if (report_prefix != NULL) {
|
||||
BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool BPY_execute_string_ex(bContext *C, const char *imports[], const char *expr, bool use_eval)
|
||||
{
|
||||
BLI_assert(expr);
|
||||
PyGILState_STATE gilstate;
|
||||
PyObject *main_mod = NULL;
|
||||
PyObject *py_dict, *retval;
|
||||
bool ok = true;
|
||||
|
||||
if (expr[0] == '\0') {
|
||||
return ok;
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
PyC_MainModule_Backup(&main_mod);
|
||||
|
||||
py_dict = PyC_DefaultNameSpace("<blender string>");
|
||||
|
||||
if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
|
||||
Py_DECREF(py_dict);
|
||||
retval = NULL;
|
||||
}
|
||||
else {
|
||||
retval = PyRun_String(expr, use_eval ? Py_eval_input : Py_file_input, py_dict, py_dict);
|
||||
}
|
||||
|
||||
if (retval == NULL) {
|
||||
ok = false;
|
||||
BPy_errors_to_report(CTX_wm_reports(C));
|
||||
}
|
||||
else {
|
||||
Py_DECREF(retval);
|
||||
}
|
||||
|
||||
PyC_MainModule_Restore(main_mod);
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool BPY_execute_string(bContext *C, const char *imports[], const char *expr)
|
||||
{
|
||||
return BPY_execute_string_ex(C, imports, expr, true);
|
||||
}
|
||||
|
||||
void BPY_modules_load_user(bContext *C)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
@@ -834,7 +506,7 @@ void BPY_modules_load_user(bContext *C)
|
||||
}
|
||||
}
|
||||
else {
|
||||
BPY_execute_text(C, text, NULL, false);
|
||||
BPY_run_text(C, text, NULL, false);
|
||||
|
||||
/* Check if the script loaded a new file. */
|
||||
if (bmain != CTX_data_main(C)) {
|
||||
|
391
source/blender/python/intern/bpy_interface_run.c
Normal file
391
source/blender/python/intern/bpy_interface_run.c
Normal file
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup pythonintern
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_text.h"
|
||||
|
||||
#include "DNA_text_types.h"
|
||||
|
||||
#include "BPY_extern.h"
|
||||
#include "BPY_extern_run.h"
|
||||
|
||||
#include "bpy_capi_utils.h"
|
||||
#include "bpy_traceback.h"
|
||||
|
||||
#include "../generic/py_capi_utils.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Private Utilities
|
||||
* \{ */
|
||||
|
||||
static void python_script_error_jump_text(Text *text)
|
||||
{
|
||||
int lineno;
|
||||
int offset;
|
||||
python_script_error_jump(text->id.name + 2, &lineno, &offset);
|
||||
if (lineno != -1) {
|
||||
/* select the line with the error */
|
||||
txt_move_to(text, lineno - 1, INT_MAX, false);
|
||||
txt_move_to(text, lineno - 1, offset, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* returns a dummy filename for a textblock so we can tell what file a text block comes from */
|
||||
static void bpy_text_filename_get(char *fn, const Main *bmain, size_t fn_len, const Text *text)
|
||||
{
|
||||
BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bmain, &text->id), SEP, text->id.name + 2);
|
||||
}
|
||||
|
||||
static bool python_script_exec(
|
||||
bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const bool do_jump)
|
||||
{
|
||||
Main *bmain_old = CTX_data_main(C);
|
||||
PyObject *main_mod = NULL;
|
||||
PyObject *py_dict = NULL, *py_result = NULL;
|
||||
PyGILState_STATE gilstate;
|
||||
|
||||
BLI_assert(fn || text);
|
||||
|
||||
if (fn == NULL && text == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
PyC_MainModule_Backup(&main_mod);
|
||||
|
||||
if (text) {
|
||||
char fn_dummy[FILE_MAXDIR];
|
||||
bpy_text_filename_get(fn_dummy, bmain_old, sizeof(fn_dummy), text);
|
||||
|
||||
if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */
|
||||
char *buf;
|
||||
PyObject *fn_dummy_py;
|
||||
|
||||
fn_dummy_py = PyC_UnicodeFromByte(fn_dummy);
|
||||
|
||||
buf = txt_to_buf(text, NULL);
|
||||
text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1);
|
||||
MEM_freeN(buf);
|
||||
|
||||
Py_DECREF(fn_dummy_py);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
if (do_jump) {
|
||||
python_script_error_jump_text(text);
|
||||
}
|
||||
BPY_text_free_code(text);
|
||||
}
|
||||
}
|
||||
|
||||
if (text->compiled) {
|
||||
py_dict = PyC_DefaultNameSpace(fn_dummy);
|
||||
py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict);
|
||||
}
|
||||
}
|
||||
else {
|
||||
FILE *fp = BLI_fopen(fn, "r");
|
||||
|
||||
if (fp) {
|
||||
py_dict = PyC_DefaultNameSpace(fn);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Previously we used PyRun_File to run directly the code on a FILE
|
||||
* object, but as written in the Python/C API Ref Manual, chapter 2,
|
||||
* 'FILE structs for different C libraries can be different and
|
||||
* incompatible'.
|
||||
* So now we load the script file data to a buffer.
|
||||
*
|
||||
* Note on use of 'globals()', it's important not copy the dictionary because
|
||||
* tools may inspect 'sys.modules["__main__"]' for variables defined in the code
|
||||
* where using a copy of 'globals()' causes code execution
|
||||
* to leave the main namespace untouched. see: T51444
|
||||
*
|
||||
* This leaves us with the problem of variables being included,
|
||||
* currently this is worked around using 'dict.__del__' it's ugly but works.
|
||||
*/
|
||||
{
|
||||
const char *pystring =
|
||||
"with open(__file__, 'rb') as f:"
|
||||
"exec(compile(f.read(), __file__, 'exec'), globals().__delitem__('f') or globals())";
|
||||
|
||||
fclose(fp);
|
||||
|
||||
py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict);
|
||||
}
|
||||
#else
|
||||
py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
|
||||
fclose(fp);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
PyErr_Format(
|
||||
PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno));
|
||||
py_result = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!py_result) {
|
||||
if (text) {
|
||||
if (do_jump) {
|
||||
/* ensure text is valid before use, the script may have freed its self */
|
||||
Main *bmain_new = CTX_data_main(C);
|
||||
if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->texts, text) != -1)) {
|
||||
python_script_error_jump_text(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
BPy_errors_to_report(reports);
|
||||
}
|
||||
else {
|
||||
Py_DECREF(py_result);
|
||||
}
|
||||
|
||||
if (py_dict) {
|
||||
#ifdef PYMODULE_CLEAR_WORKAROUND
|
||||
PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItem(PyImport_GetModuleDict(),
|
||||
bpy_intern_str___main__);
|
||||
PyObject *dict_back = mmod->md_dict;
|
||||
/* freeing the module will clear the namespace,
|
||||
* gives problems running classes defined in this namespace being used later. */
|
||||
mmod->md_dict = NULL;
|
||||
Py_DECREF(dict_back);
|
||||
#endif
|
||||
|
||||
#undef PYMODULE_CLEAR_WORKAROUND
|
||||
}
|
||||
|
||||
PyC_MainModule_Restore(main_mod);
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return (py_result != NULL);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Run Text / Filename / String
|
||||
* \{ */
|
||||
|
||||
/* Can run a file or text block */
|
||||
bool BPY_run_filepath(bContext *C, const char *filepath, struct ReportList *reports)
|
||||
{
|
||||
return python_script_exec(C, filepath, NULL, reports, false);
|
||||
}
|
||||
|
||||
bool BPY_run_text(bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump)
|
||||
{
|
||||
return python_script_exec(C, NULL, text, reports, do_jump);
|
||||
}
|
||||
|
||||
bool BPY_run_string_ex(bContext *C, const char *imports[], const char *expr, bool use_eval)
|
||||
{
|
||||
BLI_assert(expr);
|
||||
PyGILState_STATE gilstate;
|
||||
PyObject *main_mod = NULL;
|
||||
PyObject *py_dict, *retval;
|
||||
bool ok = true;
|
||||
|
||||
if (expr[0] == '\0') {
|
||||
return ok;
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
PyC_MainModule_Backup(&main_mod);
|
||||
|
||||
py_dict = PyC_DefaultNameSpace("<blender string>");
|
||||
|
||||
if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
|
||||
Py_DECREF(py_dict);
|
||||
retval = NULL;
|
||||
}
|
||||
else {
|
||||
retval = PyRun_String(expr, use_eval ? Py_eval_input : Py_file_input, py_dict, py_dict);
|
||||
}
|
||||
|
||||
if (retval == NULL) {
|
||||
ok = false;
|
||||
BPy_errors_to_report(CTX_wm_reports(C));
|
||||
}
|
||||
else {
|
||||
Py_DECREF(retval);
|
||||
}
|
||||
|
||||
PyC_MainModule_Restore(main_mod);
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool BPY_run_string(bContext *C, const char *imports[], const char *expr)
|
||||
{
|
||||
return BPY_run_string_ex(C, imports, expr, true);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Run Python & Evaluate Utilities
|
||||
*
|
||||
* Return values as plain C types, useful to run Python scripts
|
||||
* in code that doesn't deal with Python data-types.
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* \return success
|
||||
*/
|
||||
bool BPY_run_string_as_number(bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
double *r_value)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
bool ok = true;
|
||||
|
||||
if (!r_value || !expr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (expr[0] == '\0') {
|
||||
*r_value = 0.0;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
ok = PyC_RunString_AsNumber(imports, expr, "<expr as number>", r_value);
|
||||
|
||||
if (ok == false) {
|
||||
if (report_prefix != NULL) {
|
||||
BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* \return success
|
||||
*/
|
||||
bool BPY_run_string_as_string_and_size(bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
char **r_value,
|
||||
size_t *r_value_size)
|
||||
{
|
||||
BLI_assert(r_value && expr);
|
||||
PyGILState_STATE gilstate;
|
||||
bool ok = true;
|
||||
|
||||
if (expr[0] == '\0') {
|
||||
*r_value = NULL;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
ok = PyC_RunString_AsStringAndSize(imports, expr, "<expr as str>", r_value, r_value_size);
|
||||
|
||||
if (ok == false) {
|
||||
if (report_prefix != NULL) {
|
||||
BPy_errors_to_report_ex(CTX_wm_reports(C), false, false, report_prefix);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool BPY_run_string_as_string(bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
char **r_value)
|
||||
{
|
||||
size_t value_dummy_size;
|
||||
return BPY_run_string_as_string_and_size(
|
||||
C, imports, expr, report_prefix, r_value, &value_dummy_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Support both int and pointers.
|
||||
*
|
||||
* \return success
|
||||
*/
|
||||
bool BPY_run_string_as_intptr(bContext *C,
|
||||
const char *imports[],
|
||||
const char *expr,
|
||||
const char *report_prefix,
|
||||
intptr_t *r_value)
|
||||
{
|
||||
BLI_assert(r_value && expr);
|
||||
PyGILState_STATE gilstate;
|
||||
bool ok = true;
|
||||
|
||||
if (expr[0] == '\0') {
|
||||
*r_value = 0;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
ok = PyC_RunString_AsIntPtr(imports, expr, "<expr as intptr>", r_value);
|
||||
|
||||
if (ok == false) {
|
||||
if (report_prefix != NULL) {
|
||||
BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/** \} */
|
@@ -66,6 +66,7 @@
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
# include "BPY_extern.h"
|
||||
# include "BPY_extern_run.h"
|
||||
#endif
|
||||
|
||||
/* ****************************************************** */
|
||||
@@ -270,7 +271,7 @@ void WM_keyconfig_reload(bContext *C)
|
||||
{
|
||||
if (CTX_py_init_get(C) && !G.background) {
|
||||
#ifdef WITH_PYTHON
|
||||
BPY_execute_string(C, (const char *[]){"bpy", NULL}, "bpy.utils.keyconfig_init()");
|
||||
BPY_run_string(C, (const char *[]){"bpy", NULL}, "bpy.utils.keyconfig_init()");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@@ -121,8 +121,8 @@
|
||||
#include "RE_engine.h"
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
# include "BPY_extern.h"
|
||||
# include "BPY_extern_python.h"
|
||||
# include "BPY_extern_run.h"
|
||||
#endif
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
@@ -580,14 +580,14 @@ static void wm_file_read_post(bContext *C,
|
||||
if (use_userdef || reset_app_template) {
|
||||
/* Only run when we have a template path found. */
|
||||
if (BKE_appdir_app_template_any()) {
|
||||
BPY_execute_string(
|
||||
BPY_run_string(
|
||||
C, (const char *[]){"bl_app_template_utils", NULL}, "bl_app_template_utils.reset()");
|
||||
reset_all = true;
|
||||
}
|
||||
}
|
||||
if (reset_all) {
|
||||
/* sync addons, these may have changed from the defaults */
|
||||
BPY_execute_string(C, (const char *[]){"addon_utils", NULL}, "addon_utils.reset_all()");
|
||||
BPY_run_string(C, (const char *[]){"addon_utils", NULL}, "addon_utils.reset_all()");
|
||||
}
|
||||
if (use_data) {
|
||||
BPY_python_reset(C);
|
||||
@@ -924,7 +924,7 @@ void wm_homefile_read(bContext *C,
|
||||
*
|
||||
* Note that this fits into 'wm_file_read_pre' function but gets messy
|
||||
* since we need to know if 'reset_app_template' is true. */
|
||||
BPY_execute_string(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()");
|
||||
BPY_run_string(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()");
|
||||
}
|
||||
#endif /* WITH_PYTHON */
|
||||
}
|
||||
|
@@ -61,8 +61,8 @@
|
||||
# endif
|
||||
|
||||
# ifdef WITH_PYTHON
|
||||
# include "BPY_extern.h"
|
||||
# include "BPY_extern_python.h"
|
||||
# include "BPY_extern_run.h"
|
||||
# endif
|
||||
|
||||
# include "RE_engine.h"
|
||||
@@ -1780,7 +1780,7 @@ static int arg_handle_python_file_run(int argc, const char **argv, void *data)
|
||||
BLI_path_abs_from_cwd(filename, sizeof(filename));
|
||||
|
||||
bool ok;
|
||||
BPY_CTX_SETUP(ok = BPY_execute_filepath(C, filename, NULL));
|
||||
BPY_CTX_SETUP(ok = BPY_run_filepath(C, filename, NULL));
|
||||
if (!ok && app_state.exit_code_on_error.python) {
|
||||
printf("\nError: script failed, file: '%s', exiting.\n", argv[1]);
|
||||
BPY_python_end();
|
||||
@@ -1815,7 +1815,7 @@ static int arg_handle_python_text_run(int argc, const char **argv, void *data)
|
||||
bool ok;
|
||||
|
||||
if (text) {
|
||||
BPY_CTX_SETUP(ok = BPY_execute_text(C, text, NULL, false));
|
||||
BPY_CTX_SETUP(ok = BPY_run_text(C, text, NULL, false));
|
||||
}
|
||||
else {
|
||||
printf("\nError: text block not found %s.\n", argv[1]);
|
||||
@@ -1852,7 +1852,7 @@ static int arg_handle_python_expr_run(int argc, const char **argv, void *data)
|
||||
/* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
|
||||
if (argc > 1) {
|
||||
bool ok;
|
||||
BPY_CTX_SETUP(ok = BPY_execute_string_ex(C, NULL, argv[1], false));
|
||||
BPY_CTX_SETUP(ok = BPY_run_string_ex(C, NULL, argv[1], false));
|
||||
if (!ok && app_state.exit_code_on_error.python) {
|
||||
printf("\nError: script failed, expr: '%s', exiting.\n", argv[1]);
|
||||
BPY_python_end();
|
||||
@@ -1879,7 +1879,7 @@ static int arg_handle_python_console_run(int UNUSED(argc), const char **argv, vo
|
||||
# ifdef WITH_PYTHON
|
||||
bContext *C = data;
|
||||
|
||||
BPY_CTX_SETUP(BPY_execute_string(C, (const char *[]){"code", NULL}, "code.interact()"));
|
||||
BPY_CTX_SETUP(BPY_run_string(C, (const char *[]){"code", NULL}, "code.interact()"));
|
||||
|
||||
return 0;
|
||||
# else
|
||||
@@ -1952,7 +1952,7 @@ static int arg_handle_addons_set(int argc, const char **argv, void *data)
|
||||
BLI_snprintf(str, slen, script_str, argv[1]);
|
||||
|
||||
BLI_assert(strlen(str) + 1 == slen);
|
||||
BPY_CTX_SETUP(BPY_execute_string_ex(C, NULL, str, false));
|
||||
BPY_CTX_SETUP(BPY_run_string_ex(C, NULL, str, false));
|
||||
free(str);
|
||||
# else
|
||||
UNUSED_VARS(argv, data);
|
||||
|
Reference in New Issue
Block a user