❌ RuntimeError: no .dist-info at ... has pip for pipenv install managed via asdf-vm[1]#

ℹ️ Several folks who are not using asdf-vm but are facing similar issues have asked me for advice, I’ve detailed how you can troubleshoot and fix this issue on Fix runtimeerror: no .dist-info has pip in broken pipenv installs and virtualenv wheels.

Having said that, I’ve mentioned in several occasions that pipenv is my virtual environment manager of choice in Python projects and that I use it in tandem with asdf-vm[1], which allows me to seemlesly switch between Python versions depending on the project I’m working on. However, after updating one of my Ubuntu test systems (20.04.6 LTS) and installing a couple of Python versions via asdf-vm, pipenv suddenly stopped working. In this brief HOWTO I hope to provide a couple of hints as to how you may debug and ultimately fix a PipEnv installation which finds itself in a weird state.

Here you can see the behavior I was experiencing:

user@system:/tmp/test$ pipenv install

Creating a virtualenv for this project...

Pipfile: /home/user/tmp/test/Pipfile

Using /home/user/.asdf/installs/python/3.10.4/bin/python (3.10.4) to create virtualenv...

β ¦ Creating virtual environment...RuntimeError: failed to build image pip because:
Traceback (most recent call last):
  File "/home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages/virtualenv/seed/embed/via_app_data/via_app_data.py", line 57, in _install
    installer.install(creator.interpreter.version_info)
  File "/home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages/virtualenv/seed/embed/via_app_data/pip_install/base.py", line 33, in install
    self._uninstall_previous_version()
  File "/home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages/virtualenv/seed/embed/via_app_data/pip_install/base.py", line 144, in _uninstall_previous_version
    dist_name = self._dist_info.stem.split("-")[0]
  File "/home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages/virtualenv/seed/embed/via_app_data/pip_install/base.py", line 109, in _dist_info
    raise RuntimeError(f"no .dist-info at {self._image_dir}, has {', '.join(files)}")  # pragma: no cover
RuntimeError: no .dist-info at /home/user/.local/share/virtualenv/wheel/3.10/image/1/CopyPipInstall/pip-23.2.1-py3-none-any, has pip

✘ Failed creating virtual environment

[pipenv.exceptions.VirtualenvCreationException]: 
Failed to create virtual environment.

I was in a hurry and didn’t have much time to debug the issue to my satisfaction, but the mismatch between the Python version being used (3.10.4) and the lib location where pip was being looked for (/home/user/.asdf/installs/python/3.9.0/lib/python3.9) seemed suspicious right off the bat.

As any asdf user learns early on, before trying to fix things I went ahead and used asdf reshim python to discard any easily fixable issues.

user@system:/tmp/test$ asdf reshim python

user@system:/tmp/test$ pipenv install

Creating a virtualenv for this project...
Pipfile: /home/user/tmp/test/Pipfile
Using /home/user/.asdf/installs/python/3.10.4/bin/python (3.10.4) to create virtualenv...
β ¦ Creating virtual environment...RuntimeError: failed to build image pip because:
Traceback (most recent call last):
  File "/home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages/virtualenv/seed/embed/via_app_data/via_app_data.py", line 57, in _install
    installer.install(creator.interpreter.version_info)
  File "/home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages/virtualenv/seed/embed/via_app_data/pip_install/base.py", line 33, in install
    self._uninstall_previous_version()
  File "/home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages/virtualenv/seed/embed/via_app_data/pip_install/base.py", line 144, in _uninstall_previous_version
    dist_name = self._dist_info.stem.split("-")[0]
  File "/home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages/virtualenv/seed/embed/via_app_data/pip_install/base.py", line 109, in _dist_info
    raise RuntimeError(f"no .dist-info at {self._image_dir}, has {', '.join(files)}")  # pragma: no cover
RuntimeError: no .dist-info at /home/user/.local/share/virtualenv/wheel/3.10/image/1/CopyPipInstall/pip-23.2.1-py3-none-any, has pip


✘ Failed creating virtual environment
[pipenv.exceptions.VirtualenvCreationException]: 
Failed to create virtual environment.

Checking the asdf Python Version being Used#

Interestingly, asdf reports 3.9.0 as the version in use and not 3.10.4 as allegedly reported in the error output shown above.

user@system:/tmp/test$ asdf list python 
  3.10.0
  3.10.4
 *3.9.0
  3.9.6

ASDF seemed to be indeed in a weird state. pip was being looked for in the lib directory for 3.9.0, which was allegedly in-use.

pip and its asdf Alias#

pip was properly handled and aliased to /home/user/.asdf/shims/pip by asdf as expected.

user@system:/tmp/test$ type pip 
pip is /home/user/.asdf/shims/pip

Upgrading pipenv#

Before diving deeper, I simply re-installed pipenv for the Python version currently set globally via asdf (3.9.0).

user@system:/tmp/test$ pip install --upgrade pipenv 
Requirement already satisfied: pipenv in /home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages (2023.4.20)
Collecting pipenv
  Downloading pipenv-2023.8.22-py3-none-any.whl (2.7 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.7/2.7 MB 943.1 kB/s eta 0:00:00
Requirement already satisfied: certifi in /home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages (from pipenv) (2022.12.7)
Requirement already satisfied: setuptools>=67.0.0 in /home/user/.asdf/installs/python/3.9.0/lib/python3.9/site-packages (from pipenv) (67.7.2)
Collecting virtualenv>=20.24.2 (from pipenv)
  Downloading virtualenv-20.24.3-py3-none-any.whl (3.0 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.0/3.0 MB 1.0 MB/s eta 0:00:00
Collecting distlib<1,>=0.3.7 (from virtualenv>=20.24.2->pipenv)
  Downloading distlib-0.3.7-py2.py3-none-any.whl (468 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 468.9/468.9 kB 1.3 MB/s eta 0:00:00
Collecting filelock<4,>=3.12.2 (from virtualenv>=20.24.2->pipenv)
  Using cached filelock-3.12.2-py3-none-any.whl (10 kB)
Collecting platformdirs<4,>=3.9.1 (from virtualenv>=20.24.2->pipenv)
  Using cached platformdirs-3.10.0-py3-none-any.whl (17 kB)
Installing collected packages: distlib, platformdirs, filelock, virtualenv, pipenv
  Attempting uninstall: distlib
    Found existing installation: distlib 0.3.6
    Uninstalling distlib-0.3.6:
      Successfully uninstalled distlib-0.3.6
  Attempting uninstall: platformdirs
    Found existing installation: platformdirs 3.2.0
    Uninstalling platformdirs-3.2.0:
      Successfully uninstalled platformdirs-3.2.0
  Attempting uninstall: filelock
    Found existing installation: filelock 3.12.0
    Uninstalling filelock-3.12.0:
      Successfully uninstalled filelock-3.12.0
  Attempting uninstall: virtualenv
    Found existing installation: virtualenv 20.22.0
    Uninstalling virtualenv-20.22.0:
      Successfully uninstalled virtualenv-20.22.0
  Attempting uninstall: pipenv
    Found existing installation: pipenv 2023.4.20
    Uninstalling pipenv-2023.4.20:
      Successfully uninstalled pipenv-2023.4.20
Successfully installed distlib-0.3.7 filelock-3.12.2 pipenv-2023.8.22 platformdirs-3.10.0 virtualenv-20.24.3

[notice] A new release of pip is available: 23.1.2 -> 23.2.1

[notice] To update, run: pip3 install --upgrade pip
Reshimming asdf python...

Successul Creation of Virtual Environment#

Luckily, that was enough to put an end to the ordeal, at least in the meantime, as you can see below.

user@system:/tmp/test$ pipenv install
Creating a virtualenv for this project...
Pipfile: /home/user/tmp/test/Pipfile
Using default python from /home/user/.asdf/installs/python/3.9.0/bin/python3.9 (3.9.0) to create virtualenv...
β ‡ Creating virtual environment...created virtual environment CPython3.9.0.final.0-64 in 422ms
  creator CPython3Posix(dest=/home/user/.local/share/virtualenvs/test-6EXwwmxP, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/user/.local/share/virtualenv)
    added seed packages: pip==23.2.1, setuptools==68.0.0, wheel==0.41.1
  activators BashActivator,CShellActivator,FishActivator,NusystemActivator,PowerShellActivator,PythonActivator

βœ” Successfully created virtual environment!
Virtualenv location: /home/user/.local/share/virtualenvs/test-6EXwwmxP
requirements.txt found in /home/user/tmp/test instead of Pipfile! Converting...
βœ” Success!
Warning: Your Pipfile now contains pinned versions, if your requirements.txt did. 
We recommend updating your Pipfile to specify the "*" version, instead.
Pipfile.lock not found, creating...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
βœ” Success!

Addendum#

As this issue resurfaced but I couldn’t attribute it to asdf misbehaving or finding itself in a weird state I had to debug it once again. In Fix runtimeerror: no .dist-info has pip in broken pipenv installs and virtualenv wheels I explain what might be happening and how one could solve this issue if the insights and steps presented above are insufficient or one isn’t making use of asdf.

Conclusion#

The main takeaway from this short HOWTO is that asdf-vm can reach a weird state in which it believes to be using a given Python version but is actually looking for libraries and other resources in directories not associated with that Python version. Therefore, should you encounter errors similar to this, with PipEnv or otherwise, you now know to pay careful attention to the error output and draw some isnspiration from the steps I’ve outlined here.