On WSL2 `pip install virtualenv` comand hangs for too long

6.4k Views Asked by At

Under WSL2 running Ubuntu 20.04 I've tried to install virtualenv with pip running pip install virtualenv but the command just hangs printing nothing.

I terminated it and ran it again with python3 -v -m pip install virtualenv as advised here and it hangs on import 'keyring.backends.OS_X' line:

[...]
# /usr/lib/python3/dist-packages/keyring/backends/__pycache__/_OS_X_API.cpython-38.pyc matches /usr/lib/python3/dist-packages/keyring/backends/_OS_X_API.py
# code object from '/usr/lib/python3/dist-packages/keyring/backends/__pycache__/_OS_X_API.cpython-38.pyc'
# destroy keyring.backends._OS_X_API
import 'keyring.backends.OS_X' # <_frozen_importlib_external.SourceFileLoader object at 0x7fa66c4b4610>

I've tried running python -m pip install some_package_you_want as answered here but the same problem occurs.

Also, I've tried exporting PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring environment variable as advised here but unfortunately it did not solve the problem either.

EDIT: The python3 -v -m pip install virtualenv command eventually succeeded after hanging for about 5 minutes.

EDIT2: I think the problem is with the WSL2 being too slow as commented here. Eventually I've installed the virtualenv (venv) with sudo apt-get install python3-venv and activated the virtual environment with python3 -v -m venv venv command and the similar hang problem occurred now on the line import 'argparse' # <_frozen_importlib_external.SourceFileLoader object at 0x7ff1bc5f1c40> hanging here for about 2 minutes. This supports the WSL2 slowness problem.

3

There are 3 best solutions below

3
Ben JW On

Is the DISPLAY environment variable set? If so, clearing it first before running pip worked for me:

export DISPLAY=
pip install <packagename>

(Or, as a one-liner: DISPLAY= pip install <packagename>)

1
Shouv On

I did some digging with the logs, running python3 -v -m pip install packageName command for both display value set and display value empty. In case of display value empty, the following happens:

import 'jeepney.bus' # <_frozen_importlib_external.SourceFileLoader object at 0x7f8ee337f910>
# /home/shouv/.local/lib/python3.8/site-packages/jeepney/__pycache__/bus_messages.cpython-38.pyc matches /home/shouv/.local/lib/python3.8/site-packages/jeepney/bus_messages.py
# code object from '/home/shouv/.local/lib/python3.8/site-packages/jeepney/__pycache__/bus_messages.cpython-38.pyc'
# /home/shouv/.local/lib/python3.8/site-packages/jeepney/__pycache__/wrappers.cpython-38.pyc matches /home/shouv/.local/lib/python3.8/site-packages/jeepney/wrappers.py
# code object from '/home/shouv/.local/lib/python3.8/site-packages/jeepney/__pycache__/wrappers.cpython-38.pyc'
Collecting thing
  Downloading thing-0.3.3.tar.gz (12 kB)
Collecting mysql-python
  Downloading MySQL-python-1.2.5.zip (108 kB)
import 'jeepney.wrappers' # <_frozen_importlib_external.SourceFileLoader object at 0x7f8ee338baf0>

But for display value set to something, the collecting of the package does not happen, it directly goes from importing the bus to the wrappers.

Jeepney is a pure Python interface to D-Bus, a protocol for interprocess communication on desktop Linux. It's interaction with wsl2 may get a bit funny if DISPLAY value is set, and that may have caused the issue. Works perfectly with DISPLAY value set to empty though.

0
upe On

I traced the problem on my system down to this line:

import keyring

Importing keyring taking very long in WSL2 is an already known problem, that has been fixed in keyring versions ≥ 21.6.0.

Therefore, updating keyring to the latest version should solve the problem:

pip install -U keyring

or rather

DISPLAY= pip install -U keyring