Fix runtimeerror: no .dist-info has pip in broken pipenv installs and virtualenv wheels#

As mentioned in ❌ RuntimeError: no .dist-info at ... has pip for pipenv install managed via asdf-vm, I was initially confronted with issue some weeks ago but could attribute and fix the problem to asdf misbehaving. The issue, however, resurfaced and that was no longer the case. To my surprise, asdf seemed to be behaving as expected and was therefore of no relevance to the problem I was observing:

user@system:/tmp/test$ pipenv install
Creating a virtualenv for this project...
Pipfile: /tmp/test/Pipfile
Using /home/user/.asdf/installs/python/3.10.13/bin/python3 (3.10.13) 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.10.13/lib/python3.10/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.10.13/lib/python3.10/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.10.13/lib/python3.10/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.10.13/lib/python3.10/site-packages/virtualenv/seed/embed/via_app_data/pip_install/base.py", line 110, in _dist_info
    raise RuntimeError(msg)  # 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

If you are experiencing this problem and do not use asdf, this post might be of help as I managed to further narrow down its root cause.

Although my original problem at the time seemed to be due to asdf reaching a weird state, and that might as well have been the issue, I’ve started to believe that problems of the form no .dist-info at trace their roots all the way to pipenv and virtualenv, or rather Python’s venv, functionality, which is used heavily by the former, and likely have nothing to do with asdf.

I noticed that, on some systems I oversee, any virtual environment created via pipenv would fail if it was created with a given Python version, say 3.10.*, as base. For the asdf users among us, yes I did of course install the given Python versions prior to creating associated virtual environments, via asdf install python 3.10.13 for example.

It didn’t matter whether I was attempting to create the virtual environments via pipenv install with a respectively set .tool-versions to python 3.10.13 for asdf, python -m pipenv install with said version as global asdf Python version, via pipenv install --python 3.10.13, or python -m pipenv install --python 3.10.13; I would always receive the same error:

user@system:/tmp/310$ python -m pipenv install --python 3.10.13
Creating a virtualenv for this project...
Pipfile: /tmp/310/Pipfile
Using /home/user/.asdf/installs/python/3.10.13/bin/python3 (3.10.13) 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.10.13/lib/python3.10/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.10.13/lib/python3.10/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.10.13/lib/python3.10/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.10.13/lib/python3.10/site-packages/virtualenv/seed/embed/via_app_data/pip_install/base.py", line 110, in _dist_info
    raise RuntimeError(msg)  # 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

This made me think, so I looked into the directory where the alleged .dist-info directory was missing:

user@system:~$ ls /home/user/.local/share/virtualenv/wheel/3.10/image/1/CopyPipInstall/pip-23.2.1-py3-none-any
pip

There was, indeed, nothing resembling a .dist-info directory. Upon seeing this, I compared this output with a Python version for which the virtual environment creation proceeded without major issues such as 3.11:

user@system:/tmp/311$ pipenv install
Creating a virtualenv for this project...
Pipfile: /tmp/311/Pipfile
Using default python from /home/user/.asdf/installs/python/3.11.0/bin/python3.11 (3.11.0) to create virtualenv...
⠋ Creating virtual environment...created virtual environment CPython3.11.0.final.0-64 in 2162ms
  creator CPython3Posix(dest=/home/user/.local/share/virtualenvs/311-533keeiq, 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.2.0, wheel==0.41.2
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

✔ Successfully created virtual environment!
Virtualenv location: /home/user/.local/share/virtualenvs/311-533keeiq
Creating a Pipfile for this project...
Pipfile.lock not found, creating...
Locking [packages] dependencies...
Locking [dev-packages] dependencies...
Updated Pipfile.lock (a36a5392bb1e8bbc06bfaa0761e52593cf2d83b486696bf54667ba8da616c839)!
Installing dependencies from Pipfile.lock (16c839)...
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

Of course, the result was unsurprising, as shown below there were two additional entries present: the pip-23.2.1.dist-info directory and the pip-23.2.1.virtualenv file.

user@system:~$ ls /home/user/.local/share/virtualenv/wheel/3.11/image/1/CopyPipInstall/pip-23.2.1-py3-none-any
pip  pip-23.2.1.dist-info  pip-23.2.1.virtualenv

It’s been a long time since I dove deep into the way virtualenv creates and manages virtual environments[1], so I cannot say for sure what is the exact purpose for the directories present within /home/user/.local/share/virtualenv/wheel/ which are named after each minor Python version or the elements listed above. One thing is clear, though, pipenv was trying to find pip-23.2.1.dist-info in /home/user/.local/share/virtualenv/wheel/3.10/image/1/CopyPipInstall/pip-23.2.1-py3-none-any and wasn’t finding it.

I assumed, that in order to fix the aforementioned issue one could either copy the missing directory from another /wheel subdirectory associated with properly operating virtual environments or trigger the re-creation of the problematic wheel directory altogether. I tested both hypotheses and verified that either resolve the problem.

The initial, quick and dirty, solution means cp -r of 3.11/image/1/CopyPipInstall/pip-23.2.1-py3-none-any/pip-23.2.1.dist-info into 3.10/image/1/CopyPipInstall/pip-23.2.1-py3-none-any/ is enough to trick pipenv into believing everything is alright and it should proceed with the creation of the virtual environment.

However, and in an effort to leave the system in a sane and predictable state, I opted for the later solution and went ahead with the removal of /home/user/.local/share/virtualenv/wheel/3.10. After making sure asdf was using Python 3.10.13 and issuing pipenv install, I could verify that the contents of the 3.10 wheel resembled the properly operating 3.11 one where it matters:

user@system:~$ ls /home/user/.local/share/virtualenv/wheel/3.10/image/1/CopyPipInstall/pip-23.2.1-py3-none-any
pip  pip-23.2.1.dist-info  pip-23.2.1.virtualenv

After this, I could create virtual environments via pipenv without issue for 3.10.* versions:

user@system:~$ pipenv install
Creating a virtualenv for this project...
Pipfile: /tmp/310/Pipfile
Using default python from /home/user/.asdf/installs/python/3.10.13/bin/python3.10 (3.10.13) to create virtualenv...
⠙ Creating virtual environment...created virtual environment CPython3.10.13.final.0-64 in 504ms
  creator CPython3Posix(dest=/home/user/.local/share/virtualenvs/310-533keeiq, 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.2.0, wheel==0.41.2
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

✔ Successfully created virtual environment!
Virtualenv location: /home/user/.local/share/virtualenvs/310-533keeiq
Creating a Pipfile for this project...
Pipfile.lock not found, creating...
Locking [packages] dependencies...
Locking [dev-packages] dependencies...
Updated Pipfile.lock (a36a5392bb1e8bbc06bfaa0761e52593cf2d83b486696bf54667ba8da616c839)!
Installing dependencies from Pipfile.lock (16c839)...
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

Final Remarks#

I sincerely hope this article was useful to you, as this issue has resulted in much frustration. Feedback via social media or email is always welcome. You can subscribe to my newsletter by entering your email on the sidebar if you are interested in receiving updates whenever I write something new.