Mismatch between sys.executable and sys.version in Python
Both @Graeme
The fact that python may be unable to retrieve this suggests that it
is doing its own PATH search (…)
and @twalberg
(…) it looks like sys.executable searches the current PATH instead of
resolving argv[0] (or maybe because argv[0] is simpy python in this
case...), (…)
were basically right. I was reluctant to believe that Python does something so simple (silly?) as using PATH
to locate itself but this is true.
Python's sys
module is implemented in Python/sysmodule.c
file. As of version 2.7.6, sys.executable
is set at line 1422 like this:
SET_SYS_FROM_STRING("executable",
PyString_FromString(Py_GetProgramFullPath()));
Py_GetProgramFullPath()
function is defined in file Modules/getpath.c
starting from line 701:
char *
Py_GetProgramFullPath(void)
{
if (!module_search_path)
calculate_path();
return progpath;
}
Function calcuate_path()
is defined in the same file and contains the following comment:
/* If there is no slash in the argv0 path, then we have to
* assume python is on the user's $PATH, since there's no
* other way to find a directory to start the search from. If
* $PATH isn't exported, you lose.
*/
As can be seen in my case, one loses also when the first Python on exported $PATH
is different than the Python being run.
More information on the process of calculating placement of interpreter's executable can be found at the top of getpath.c
file:
Before any searches are done, the location of the executable is
determined. If argv[0] has one or more slashes in it, it is used
unchanged. Otherwise, it must have been invoked from the shell's path,
so we search $PATH for the named executable and use that. If the
executable was not found on $PATH (or there was no $PATH environment
variable), the original argv[0] string is used.Next, the executable location is examined to see if it is a symbolic
link. If so, the link is chased (correctly interpreting a relative
pathname if one is found) and the directory of the link target is used.
Let's make a couple of tests to verify the above:
If argv[0] has one or more slashes in it, it is used unchanged.
[user@localhost ~]$ sudo /usr/local/bin/python what_python.py
/usr/local/bin/python
2.7.6 (default, Feb 27 2014, 17:05:07)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]
Ok.
If the executable was not found on $PATH (or there was no $PATH environment variable), the original argv[0] string is used.
[user@localhost ~]$ sudo PATH= python what_python.py
<empty line>
2.7.6 (default, Feb 27 2014, 17:05:07)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]
Wrong. In this case statement from sys module's documentation is true – If Python is unable to retrieve the real path to its executable, sys.executable will be an empty string or None. .
Let's see if adding location of python's binary back to the PATH
(after sudo had removed it) fixes the problem:
[user@localhost ~]$ sudo PATH=$PATH python what_python.py
/usr/local/bin/python
2.7.6 (default, Feb 27 2014, 17:05:07)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)]
It does.
Related:
- Python issue 7774 – sys.executable: wrong location if zeroth command argument is modified.
- Python issue 10835 – sys.executable default and altinstall
- python-dev mailing list thread – towards a stricter definition of sys.executable
- Stackoverflow question – how to find the location of the executable in C
Is sys.version_info reliable for Python version checking?
Yes. sys.version_info
is a reliable way to determine Python version.
See Python 3 documentation and Python 2 documentation.
Note: sys.version_info
is reliable, but not sys.version
:
sys.version
A string containing the version number of the Python interpreter plus additional information on the build number and compiler used. This string is displayed when the interactive interpreter is started. Do not extract version information out of it, rather, use
version_info
and the functions provided by theplatform
module.
If you're worried about bad modules changing the values of sys.version_info
or something else, you can force a reload of <module 'sys' (built-in)>
:
import sys
sys.version_info = "boo"
print(sys.version_info) # boo
sys.modules.pop("sys")
import sys # reloaded
print(sys.version_info)
# Output: sys.version_info(major=3, minor=6, ...
How do you get Visual Studio Code to use different Python interpreter?
Open command pallete with F1
(on Windows) and type Python: Select Interpreter
.
ipython reads wrong python version
Okay quick fix:
which python
gives you /usr/bin/python
, right? Do
which ipython
and I bet that'll be /usr/local/bin/ipython
. Let's look inside:
Edit 9/7/16 -- The file now looks like this:
cat /usr/local/bin/ipython
#!/usr/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from IPython import start_ipython
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(start_ipython())
And mine works properly like this, but my situation isn't exactly like the OP's.
Original answer -- 9/30/13:
cat /usr/local/bin/ipython
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'ipython==0.12.1','console_scripts','ipython'
__requires__ = 'ipython==0.12.1'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('ipython==0.12.1', 'console_scripts', 'ipython')()
)
Aha - open /usr/local/bin/ipython
in your editor (with privileges), and change the first line to
#!/usr/local/bin/python
save, start iPython, should say it's using the version you want now.
ProtocolConnectionException in the context of Python versions
I suspect this Python version stuff is a red herring. What's happening is this code is attempting to listen on a TCP port (whatever self.port
is), but something else is already listening there. On Linux, you could run sudo netstat -anp | grep LISTEN
to figure out what process that is.
Related Topics
How to Sudo the Current Process
Os.System() Execute Command Under Which Linux Shell
Determine If Package Installed with Yum Python API
How to Set File Permissions in Python3
Understanding Python Fork and Memory Allocation Errors
Python3 Cgi Https Server Fails on Unix
Convert a Gtk Python Script to C
Difference Between Pip and Conda
What Is the Naming Convention in Python For Variable and Function
How to Get the Full Path of the Current File'S Directory
How to Convert Seconds to Hours, Minutes and Seconds
How to Load All Modules in a Folder
How to Prompt For User Input and Read Command-Line Arguments
Plt.Figure.Figure.Show() Does Nothing When Not Executing Interactively