Description
Bug report
Bug description:
I'm noticing a discrepancy between running embedded Python with isolated=1
and site_import=0
, and running a Python script with the equivalent flags -I -S
. I'm unsure if this is intentional or not, or if this has any actual consequences, so I'm reporting it to be sure. This is potentially related to #131484.
The difference I'm seeing is that when running a python script, the 4th path in sys.path
is C:\Python313
; running an embedded application, the 4th path is the embedding executable's parent directory, e.g. C:\Work\Demos\py-embed-path\build\Debug
.
In fact, in both cases, the 4th path is sys.executable
's parent directory. But for embedded applications, I'm unsure if this is intentional, or if it should in fact also be C:\Python313
, the directory containing python313.dll
that the executable loaded.
To reproduce
On Windows, with Python 3.13.3 installed, given the following source files:
# script.py
import sys, os
print(f'{sys.executable=}')
print(f'{sys.prefix=}')
print(f'{os.getcwd()=}')
print('sys.path:')
for path in sys.path:
print(f'- {path}')
// main.cpp
#include <Python.h>
int main() {
PyConfig config;
PyConfig_InitIsolatedConfig(&config);
config.site_import = 0;
PyStatus s = Py_InitializeFromConfig(&config);
PyConfig_Clear(&config);
if (PyStatus_Exception(s)) {
Py_ExitStatusException(s);
}
PyRun_SimpleString(R"(
import sys, os
print(f'{sys.executable=}')
print(f'{sys.prefix=}')
print(f'{os.getcwd()=}')
print('sys.path:')
for path in sys.path:
print(f'- {path}')
)");
Py_Finalize();
return 0;
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project(PythonPathRepro)
find_package(Python3 3.13 REQUIRED COMPONENTS Development.Embed)
add_executable(python_path_repro main.cpp)
target_link_libraries(python_path_repro PRIVATE Python3::Python)
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# disable Python's auto-linking
target_link_options(python_path_repro PRIVATE "/NODEFAULTLIB:python313_d.lib" "/NODEFAULTLIB:python313.lib")
endif()
Running the python script with the -I -S
flags produces the following:
λ py -3.13 -I -S script.py
sys.executable='C:\\Python313\\python.exe'
sys.prefix='C:\\Python313'
os.getcwd()='C:\\Work\\Demos\\py-embed-path'
sys.path:
- C:\Python313\python313.zip
- C:\Python313\DLLs
- C:\Python313\Lib
- C:\Python313
Compiling and running the C++ code produces the following:
(I made sure to run the code from a different directory than the executable to demonstrate that the path is deduced from the executable, not from the cwd)
λ build\Debug\python_path_repro.exe
sys.executable='C:\\Work\\Demos\\py-embed-path\\build\\Debug\\python_path_repro.exe'
sys.prefix='C:\\Python313'
os.getcwd()='C:\\Work\\Demos\\py-embed-path'
sys.path:
- C:\Python313\python313.zip
- C:\Python313\DLLs
- C:\Python313\Lib
- C:\Work\Demos\py-embed-path\build\Debug
These two modes of executions produce a different value for the fourth item in sys.path
.
Notes
I understand that the repro above is not the usual use-case for embedded Python, and that it's better to include the Python "Windows embeddable package" in the app and use that, and possibly fully control sys.path
through config.search_module_paths
or python313._pth
in the embeddable package. I am indeed using the embeddable package for the actual app. But the use-case I'm working with here is rather when building and running unit tests on developers' machines using their Python installation. Installing the embeddable package just to run the unit tests is something I would like to avoid, if possible, considering a full Python installation is already required to build the library and tests in the first place.
As I stated above, this difference in behavior is not actually causing any problems for the moment. I'm just reporting it in case it could potentially cause problems in the future, and to understand if this behavior is intended or not.
p.s. is there a reason for sys.path
to contain C:\Python313
when running scripts with python.exe
? By default, Python does not seem to have any modules available there. And the embeddable package which does have modules in its root directory also provides a python313._pth
which overrides sys.path
to include .
.
CPython versions tested on:
3.13
Operating systems tested on:
Windows