diff --git a/CHANGELOG.md b/CHANGELOG.md index 4051db1b..12d6650a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## Unreleased +* Bug fix: preserve the selected Python executable when embedding Python 3.10 on Windows. * Bug fix: avoid precompilation cache miss when `check_bounds` option set. * Bug fix: `juliacall` set the environment variable `JULIA_PYTHONCALL_EXECUTABLE` instead of `JULIA_PYTHONCALL_EXE`, so child Julia processes resolved a new diff --git a/pytest/test_all.py b/pytest/test_all.py index 9cdc8ce4..151a7361 100644 --- a/pytest/test_all.py +++ b/pytest/test_all.py @@ -5,6 +5,37 @@ def test_import(): import juliacall +def test_pythoncall_executable_runs_python(): + import subprocess + import sys + + from juliacall import Main as jl + + code = '''\ +using PythonCall +sys = pyimport("sys") +@assert pyconvert(String, sys.executable) == only(ARGS) +subprocess = pyimport("subprocess") +output = subprocess.check_output([sys.executable, "-c", "print(6, end='')"]) +print(pyconvert(String, output.decode())) +''' + result = subprocess.run( + [ + str(jl.seval("first(Base.julia_cmd().exec)")), + "--project=" + str(jl.seval("dirname(Base.active_project())")), + "--startup-file=no", + "-e", + code, + sys.executable, + ], + capture_output=True, + text=True, + timeout=180, + ) + assert result.returncode == 0, result.stderr + assert result.stdout == "6" + + def test_newmodule(): import juliacall diff --git a/src/C/context.jl b/src/C/context.jl index 6ccdab89..ea469ffd 100644 --- a/src/C/context.jl +++ b/src/C/context.jl @@ -278,6 +278,16 @@ function init_context() CTX.pyprogname_w = Base.cconvert(Cwstring, CTX.pyprogname) Py_SetProgramName(pointer(CTX.pyprogname_w)) + # Python 3.10 on Windows ignores program_name when resolving the executable. + if Sys.iswindows() && startswith(Base.unsafe_string(Py_GetVersion()), "3.10.") + ccall( + dlsym(CTX.lib_ptr, :_Py_SetProgramFullPath), + Cvoid, + (Ptr{Cwchar_t},), + pointer(CTX.pyprogname_w), + ) + end + # Start the interpreter and register exit hooks Py_InitializeEx(0) atexit() do