JuliaPy / PyCall.jl

Package to call Python functions from the Julia language
MIT License
1.46k stars 187 forks source link

Python's `sys.executable` points to Julia's binary on Windows #958

Open pedromxavier opened 2 years ago

pedromxavier commented 2 years ago

When Python's sys module is loaded via pyimport("sys") its executable returns Julia's path instead of Python's. The same doesn't happen on Linux.

To reproduce this issue (Windows 10, Julia 1.7.0, PyCall 1.93.0):

julia> using PyCall

julia> sys = pyimport("sys")
PyObject <module 'sys' (built-in)>

julia> sys.executable
"C:\\Users\\User\\AppData\\Local\\Programs\\Julia-1.7.0\\bin\\julia.exe"
stevengj commented 2 years ago

Isn't that correct? We are not running python.exe.

stevengj commented 2 years ago

Oh, I see, the definition of sys.executable in the Python docs is

A string giving the absolute path of the executable binary for the Python interpreter, on systems where this makes sense. If Python is unable to retrieve the real path to its executable, sys.executable will be an empty string or None.

(emphasis added)

See also these discussions about sys.executable for embedded python:

It seems like this happens a lot for programs embedding Python. In our case, PyCall.python is the path of the Python interpreter corresponding to the libpython we are linking to, so we should be able to set sys.executable to this.

pedromxavier commented 2 years ago

Very interesting definitions. On Linux the behavior is the following:

julia> using PyCall

julia> sys = pyimport("sys")
PyObject <module 'sys' (built-in)>

julia> sys.executable
"/usr/bin/python3"

as ,IMO, was expected. Apparently, there is no clear correspondence between PyCall.python and pyimport("sys").executable. This brings some inconsistency across platforms, getting even more unpredictable outcomes when PyCall.conda == true, which is the main point of #958.

stevengj commented 2 years ago

It looks like sys.executable is set from the configuration, and apparently we can use this API to change it when we initialize Python by using Py_InitializeFromConfig.

nicolaefilat commented 3 months ago

Is there a fix for this issue? I have to use a python library that makes use somewhere of sys.executable and because I am on windows that points to julia and the code crashes. My current workaround was to modify the library code directly to point to the conda's python

stevengj commented 3 months ago

Ideally, someone has to figure out the PyConfig API and make a patch to set this correctly.

In the meantime, one could simply do:

pyimport("sys").executable = PyCall.python