I have a script (speedtest-cli) that requires Python2, but need to use Python3 for Ansible.
Through update-alternatives I’ve set "auto mode" and Python3. I suppose in my naivity I had somehow expected this would automatically use Python2 for the script that requires that, but it doesn’t work.
What is the best way to deal with this?
Debian Buster
Update 1: Tried the suggestion by furas. It didn’t change anything, the script still throws the same errors ….
rcd@gw:~$ python2 speedtest.py
Traceback (most recent call last):
File "/usr/bin/speedtest-cli", line 6, in <module>
from pkg_resources import load_entry_point
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 3019, in <module>
@_call_aside
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 3003, in _call_aside
f(*args, **kwargs)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 3032, in _initialize_master_working_set
working_set = WorkingSet._build_master()
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 655, in _build_master
ws.require(__requires__)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 963, in require
needed = self.resolve(parse_requirements(requirements))
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 849, in resolve
raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'speedtest-cli==1.0.0' distribution was not found and is required by the application
Traceback (most recent call last):
File "speedtest.py", line 12, in <module>
ping = ping[0].replace(',', '.')
IndexError: list index out of range
Note how it addresses /usr/lib/python3 although I run python2 ….
rcd@gw:~$ type python2
python2 is hashed (/usr/bin/python2)
rcd@gw:~$ type python
python is /usr/bin/python
rcd@gw:~$ type python3
python3 is /usr/bin/python3
rcd@gw:~$ ls -al /usr/bin/python*
lrwxrwxrwx 1 root root 24 Jun 10 19:03 /usr/bin/python -> /etc/alternatives/python
lrwxrwxrwx 1 root root 9 Jan 24 2017 /usr/bin/python2 -> python2.7
-rwxr-xr-x 1 root root 3779512 Sep 26 2018 /usr/bin/python2.7
lrwxrwxrwx 1 root root 9 Jan 20 2017 /usr/bin/python3 -> python3.5
-rwxr-xr-x 2 root root 4751184 Sep 27 2018 /usr/bin/python3.5
lrwxrwxrwx 1 root root 33 Sep 27 2018 /usr/bin/python3.5-config -> x86_64-linux-gnu-python3.5-config
-rwxr-xr-x 2 root root 4751184 Sep 27 2018 /usr/bin/python3.5m
lrwxrwxrwx 1 root root 34 Sep 27 2018 /usr/bin/python3.5m-config -> x86_64-linux-gnu-python3.5m-config
lrwxrwxrwx 1 root root 16 Jan 20 2017 /usr/bin/python3-config -> python3.5-config
lrwxrwxrwx 1 root root 10 Jan 20 2017 /usr/bin/python3m -> python3.5m
lrwxrwxrwx 1 root root 17 Jan 20 2017 /usr/bin/python3m-config -> python3.5m-config
Then I tried with virtualenv ….
rcd@gw:~$ virtualenv -p /usr/bin/python2.7 venv2.7
Running virtualenv with interpreter /usr/bin/python2.7
New python executable in /home/rcd/venv2.7/bin/python2.7
Also creating executable in /home/rcd/venv2.7/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
rcd@gw:~$ source venv2.7/bin/activate
Run with python2.7, exactly same result …
(venv2.7) rcd@gw:~$ python2 speedtest.py
Traceback (most recent call last):
File "/usr/bin/speedtest-cli", line 6, in <module>
from pkg_resources import load_entry_point
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 3019, in <module>
@_call_aside
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 3003, in _call_aside
f(*args, **kwargs)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 3032, in _initialize_master_working_set
working_set = WorkingSet._build_master()
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 655, in _build_master
ws.require(__requires__)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 963, in require
needed = self.resolve(parse_requirements(requirements))
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 849, in resolve
raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'speedtest-cli==1.0.0' distribution was not found and is required by the application
Traceback (most recent call last):
File "speedtest.py", line 12, in <module>
ping = ping[0].replace(',', '.')
IndexError: list index out of range
I don’t know what’s going on here, no matter what I do it seems to want to run with Python3 ….
3
Answers
speedtest.py is in fact a python script running speedtest-cli which is another python script.
The solution was to update the first shebang line in the speedtest-cli script to explicitly use python2, then it worked.
Thanks for the help!!
Standard method is to use
shebang
(#!
) in first line of script to inform system what program it has to use to execute this script –Python 2
,Python 3
,bash
,perl
,PHP
, etc.or more universal and more popular
And script has to be executable so it need
chmod +x script.py
Of course you can always execute it manually
At times it is not efficient to hardcode a script with a specific interpreter like python2 or python3 as it might not be compatible for different versions and more importantly when a particular version is obsolete. I generally recommend a command line argument like in case of ansible run you can use ‘ansible_python_interpreter=/usr/bin/python3’ (python2 in your case) on a command line for smooth flow of a task.
Nevertheless you have a workaround which should be fine I believe.