1

I upgraded Python on my system from Python 3.5 to 3.6, and now all my virtualenvs created in Python 3.5 are no longer usable. How can I get a list of packages installed in a Python 3.5 virtualenv when I have only Python 3.6 installed? I need to setup a new Python 3.6 virtualenv with the same packages as in the old Python 3.5 virtualenv.

I know that I can look inside the lib/python3.5/site-packages directory and make the list manually, but I would prefer an automatic way of running e.g. pip freeze against the old virtual environment. I would prefer not to re-install the old version of Python.

I have tried the python -m venv --upgrade command, which has the help text "Upgrade the environment directory to use this version of Python, assuming Python has been upgraded in-place.". However, this doesn't actually reinstall the packages in the virtualenv, it just creates an essentially empty directory named lib/python3.6/site-packages. Furthermore, I had to remove the broken symlink bin/python3.5 in the venv in order to even run python -m venv --upgrade against the old virtualenv.

Mathias Rav
  • 2,808
  • 14
  • 24

2 Answers2

1

It seems easy to get a virtualenv into a situation where it will not upgrade. You can probably fix the venv manually, but I think it is easiest to start again.

In brief:

  • Create a new virtualenv
  • Copy into it the directories in your old venv that are not part of the venv environment.
  • In the old environment: ls -1 lib/python3.5/site-packages > requirements.txt, then clean it up by hand
  • In the new environment pip install -r requirements.txt

See this related question: Update a Python virtualenv?

Community
  • 1
  • 1
resplin
  • 436
  • 5
  • 12
1

Use pkg_resources.find_on_path() to find packages using the same logic as pip freeze. This works even when the virtualenv is for an older version of Python:

rav@novascotia:~/venvs$ python
Python 3.6.1 (default, Mar 27 2017, 00:27:06) 
[GCC 6.3.1 20170306] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg_resources
>>> entries = pkg_resources.find_on_path(None, './st-courses-3.5/lib/python3.5/site-packages')
>>> print('pip install \\\n%s' % ' \\\n'.join('%s==%s' % (o.project_name, o.version) for o in entries))
pip install \
websockets==3.2 \
webencodings==0.5 \
wcwidth==0.1.7 \
...

This is the trail of code that leads from pip freeze to find_on_path:

Mathias Rav
  • 2,808
  • 14
  • 24