PyAPI: point sys.executable to the Python binary
`sys.executable` is documented to be a Python interpreter or None.
This was set to Blender's executable which caused the multiprocessing
module to spawn new instances of Blender instead of Python on WIN32.
See issue described in D7815.
Deprecate 'bpy.app.binary_path_python' & warn when using.
Blender's executable remains accessible via `bpy.app.binary_path`.
Modified 04c5471cee
, setting `sys.executable` instead of using
Py_SetProgramName, which is needed for a bundled Python installation.
This commit is contained in:
parent
911f9e00d1
commit
52b38d9c3d
Notes:
blender-bot
2023-02-14 11:25:11 +01:00
Referenced by commit81090ded0d
, Fluid: Removed binary_python from fluid script Referenced by commita877248ac2
, Fluid: Switch to binary_python
|
@ -82,10 +82,10 @@ def write_sysinfo(filepath):
|
|||
output.write("\t%r\n" % p)
|
||||
|
||||
output.write(title("Python (External Binary)"))
|
||||
output.write("binary path: %s\n" % prepr(bpy.app.binary_path_python))
|
||||
output.write("binary path: %s\n" % prepr(sys.executable))
|
||||
try:
|
||||
py_ver = prepr(subprocess.check_output([
|
||||
bpy.app.binary_path_python,
|
||||
sys.executable,
|
||||
"--version",
|
||||
]).strip())
|
||||
except Exception as e:
|
||||
|
|
|
@ -292,36 +292,13 @@ static int bpy_app_global_flag_set__only_disable(PyObject *UNUSED(self),
|
|||
return bpy_app_global_flag_set(NULL, value, closure);
|
||||
}
|
||||
|
||||
#define BROKEN_BINARY_PATH_PYTHON_HACK
|
||||
|
||||
PyDoc_STRVAR(bpy_app_binary_path_python_doc,
|
||||
"String, the path to the python executable (read-only)");
|
||||
static PyObject *bpy_app_binary_path_python_get(PyObject *self, void *UNUSED(closure))
|
||||
"String, the path to the python executable (read-only). "
|
||||
"Deprecated! Use ``sys.executable`` instead.");
|
||||
static PyObject *bpy_app_binary_path_python_get(PyObject *UNUSED(self), void *UNUSED(closure))
|
||||
{
|
||||
/* refcount is held in BlenderAppType.tp_dict */
|
||||
static PyObject *ret = NULL;
|
||||
|
||||
if (ret == NULL) {
|
||||
/* only run once */
|
||||
char fullpath[1024];
|
||||
BKE_appdir_program_python_search(
|
||||
fullpath, sizeof(fullpath), PY_MAJOR_VERSION, PY_MINOR_VERSION);
|
||||
ret = PyC_UnicodeFromByte(fullpath);
|
||||
#ifdef BROKEN_BINARY_PATH_PYTHON_HACK
|
||||
Py_INCREF(ret);
|
||||
UNUSED_VARS(self);
|
||||
#else
|
||||
PyDict_SetItem(
|
||||
BlenderAppType.tp_dict,
|
||||
/* XXX BAAAADDDDDD! self is not a PyDescr at all! it's bpy.app!!! */ PyDescr_NAME(self),
|
||||
ret);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
Py_INCREF(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
PyErr_Warn(PyExc_RuntimeWarning, "Use 'sys.executable' instead of 'binary_path_python'!");
|
||||
return Py_INCREF_RET(PySys_GetObject("executable"));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(bpy_app_debug_value_doc,
|
||||
|
|
|
@ -306,7 +306,11 @@ void BPY_python_start(bContext *C, int argc, const char **argv)
|
|||
PyThreadState *py_tstate = NULL;
|
||||
const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL);
|
||||
|
||||
/* Not essential but nice to set our name. */
|
||||
/* Needed for Python's initialization for portable Python installations.
|
||||
* We could use #Py_SetPath, but this overrides Python's internal logic
|
||||
* for calculating it's own module search paths.
|
||||
*
|
||||
* `sys.executable` is overwritten after initialization to the Python binary. */
|
||||
{
|
||||
const char *program_path = BKE_appdir_program_path();
|
||||
wchar_t program_path_wchar[FILE_MAX];
|
||||
|
@ -354,6 +358,23 @@ void BPY_python_start(bContext *C, int argc, const char **argv)
|
|||
Py_DECREF(py_argv);
|
||||
}
|
||||
|
||||
/* Setting the program name is important so the 'multiprocessing' module
|
||||
* can launch new Python instances. */
|
||||
{
|
||||
char program_path[FILE_MAX];
|
||||
if (BKE_appdir_program_python_search(
|
||||
program_path, sizeof(program_path), PY_MAJOR_VERSION, PY_MINOR_VERSION)) {
|
||||
PyObject *py_program_path = PyC_UnicodeFromByte(program_path);
|
||||
PySys_SetObject("executable", py_program_path);
|
||||
Py_DECREF(py_program_path);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"Unable to find the python binary, "
|
||||
"the multiprocessing module may not be functional!\n");
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef WITH_FLUID
|
||||
/* Required to prevent assertion error, see:
|
||||
* https://stackoverflow.com/questions/27844676 */
|
||||
|
|
Loading…
Reference in New Issue