| 349 | #endif |
| 350 | |
| 351 | void BPY_python_start(bContext *C, int argc, const char **argv) |
| 352 | { |
| 353 | #ifndef WITH_PYTHON_MODULE |
| 354 | BLI_assert_msg(Py_IsInitialized() == 0, "Python has already been initialized"); |
| 355 | |
| 356 | /* It's necessary to disable isolation so `user-site-packages` can be used. |
| 357 | * Leave everything else disabled (mainly environment variables). */ |
| 358 | const std::optional<bool> isolated_override = ((py_use_system_env == false) && |
| 359 | (py_use_user_env == true)) ? |
| 360 | std::optional(false) : |
| 361 | std::nullopt; |
| 362 | |
| 363 | /* #PyPreConfig (early-configuration). */ |
| 364 | { |
| 365 | PyPreConfig preconfig; |
| 366 | PyStatus status; |
| 367 | |
| 368 | /* To narrow down reports where the systems Python is inexplicably used, see: #98131. */ |
| 369 | CLOG_DEBUG(BPY_LOG_INTERFACE, |
| 370 | "Initializing %s support for the systems Python environment such as 'PYTHONPATH', " |
| 371 | "%s support for the user-site directory.", |
| 372 | py_use_system_env ? "*with*" : "*without*", |
| 373 | py_use_user_env ? "*with*" : "*without*"); |
| 374 | |
| 375 | if (py_use_system_env) { |
| 376 | PyPreConfig_InitPythonConfig(&preconfig); |
| 377 | } |
| 378 | else { |
| 379 | /* Only use the systems environment variables and site when explicitly requested. |
| 380 | * Since an incorrect 'PYTHONPATH' causes difficult to debug errors, see: #72807. |
| 381 | * An alternative to setting `preconfig.use_environment = 0` */ |
| 382 | PyPreConfig_InitIsolatedConfig(&preconfig); |
| 383 | } |
| 384 | |
| 385 | if (isolated_override) { |
| 386 | preconfig.isolated = isolated_override.value(); |
| 387 | } |
| 388 | |
| 389 | /* Force UTF8 on all platforms, since this is what's used for Blender's internal strings, |
| 390 | * providing consistent encoding behavior across all Blender installations. |
| 391 | * |
| 392 | * This also uses the `surrogateescape` error handler ensures any unexpected bytes are escaped |
| 393 | * instead of raising an error. |
| 394 | * |
| 395 | * Without this `sys.getfilesystemencoding()` and `sys.stdout` for example may be set to ASCII |
| 396 | * or some other encoding - where printing some UTF8 values will raise an error. |
| 397 | * |
| 398 | * This can cause scripts to fail entirely on some systems. |
| 399 | * |
| 400 | * This assignment is the equivalent of enabling the `PYTHONUTF8` environment variable. |
| 401 | * See `PEP-540` for details on exactly what this changes. */ |
| 402 | preconfig.utf8_mode = true; |
| 403 | |
| 404 | /* Note that there is no reason to call #Py_PreInitializeFromBytesArgs here |
| 405 | * as this is only used so that command line arguments can be handled by Python itself, |
| 406 | * not for setting `sys.argv` (handled below). */ |
| 407 | status = Py_PreInitialize(&preconfig); |
| 408 | pystatus_exit_on_error(status); |
no test coverage detected