5

Context: After updating from Debian 8 to 9, Python 3.4 virtualenvs stopped working because system site-packages were all replaced by the Python 3.5 version. This answer suggests removing the old virtualenv, creating a new one, and reinstalling all packages using pip install -r requirements.txt. However, I don't have a requirements.txt for all virtualenv. I know that such file can be created with pip freeze, but for the reason stated above, pip won't work1.

Problem: I need to generate a list of the packages and their respective installed in a virtualenv that I cannot activate.

Question: Is there a way to get a list similar to the output of pip freeze for a virtualenv without actually running pip?

Note: This question is different from “Return a list of imported Python modules used in a script?” and because the requested answers should not need to access the scripts that use the virtualenv, and should also return the versions of the packages installed in the virtualenv2.


1 Namely, running pip (with any parameters) raises ImportError: No module named 'encodings'.

2 Full disclosure: I asked a similar question that was wrongly closed as duplicate.

Arcturus B
  • 5,181
  • 4
  • 31
  • 51

1 Answers1

5

Getting the list of installed packages without a working pip will be very hard. Alternatively, you can try making sense from the filenames installed in your virtualenv site-packages directory:

You can get the site-packages directory by running

python -m site

and looking for a string like

'/your/venv/lib/python3.4/site-packages'

Take that path and run

ls -d /your/venv/lib/python3.4/site-packages/*.dist-info

This should give you a list of the majority of the installed package directories in your virtualenv.

To clean up this list and create a requirements.txt file that somewhat resembles the correct syntax and data, you can use

ls -d /your/venv/lib/python3.4/site-packages/*.dist-info | xargs -I% basename % | sed 's/\.dist-info//; s/-/==/; s/_/-/' > requirements.txt

Needless to say, you probably need to clean up its contents a little bit afterwards.

Nils Werner
  • 34,832
  • 7
  • 76
  • 98
  • Awesome, thanks! Indeed, the output still needs cleaning. For instance, a package named `some-package` would be store in the directory `some_package-version.dist-info` (note that the dash has become an underscore). But this can be done manually. – Arcturus B Aug 06 '18 at 14:20
  • Didn't know about the `site` module, very useful. I've been having people open up their REPL and print `sys.path` for me to help debug environment issues...now I know a better way thanks to this answer! – Matt Messersmith Aug 06 '18 at 14:22
  • I have added another `sed` command that replaces `_` with `-` to the pipeline. However there probably are packages that actually contain an underscore. – Nils Werner Aug 06 '18 at 14:23
  • It seems that `pip` replaces `_` with `-`: https://stackoverflow.com/a/19131777/4352108, so this whole thing should not be a problem anyway. :) – Arcturus B Aug 06 '18 at 14:30