Upgrade Python in virtualenv

You use virtualenv to isolate your development environment and use specific versions of Python interpreter/compiler and dependencies.

You are not supposed to upgrade the version of Python in a virtualenv!

Broken Python Version

I accidentally upgraded  the installed version of Python and broke my virtualenvs.

$ python --version
dyld: Library not loaded: @executable_path/../.Python
  Referenced from: /Users/hanxue/.virtualenvs/piwikapi/bin/python
  Reason: image not found
Trace/BPT trap: 5
pTrace/BPT trap: 5


The Python executables within virtualenv are broken links now


$ file .Python 
.Python: broken symbolic link to /usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/Python
$ file lib/python3.6/config-3.6m-darwin 
lib/python3.6/config-3.6m-darwin: broken symbolic link to /usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/config-3.6m-darwin

Directly reinstalling virtualenv will not work, and you will see plenty of FileExistsError


$ virtualenv --python=/usr/local/opt/python3/bin/python3 .
Running virtualenv with interpreter /usr/local/opt/python3/bin/python3
Using base prefix '/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6'
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/virtualenv.py", line 351, in copyfile
    os.symlink(srcpath, dest)
FileExistsError: [Errno 17] File exists: '/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/config-3.6m-darwin' -> '/Users/hanxue/.virtualenvs/piwikapi/lib/python3.6/config-3.6m-darwin'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/virtualenv.py", line 2328, in <module>
    main()
  File "/usr/local/lib/python3.6/site-packages/virtualenv.py", line 713, in main
    symlink=options.symlink)
  File "/usr/local/lib/python3.6/site-packages/virtualenv.py", line 925, in create_environment
    site_packages=site_packages, clear=clear, symlink=symlink))
  File "/usr/local/lib/python3.6/site-packages/virtualenv.py", line 1130, in install_python
    copyfile(join(stdlib_dir, fn), join(lib_dir, fn), symlink)
  File "/usr/local/lib/python3.6/site-packages/virtualenv.py", line 354, in copyfile
    copyfileordir(src, dest, symlink)
  File "/usr/local/lib/python3.6/site-packages/virtualenv.py", line 329, in copyfileordir
    shutil.copytree(src, dest, symlink)
  File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/shutil.py", line 315, in copytree
    os.makedirs(dst)
  File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/os.py", line 220, in makedirs
    mkdir(name, mode)
FileExistsError: [Errno 17] File exists: '/Users/hanxue/.virtualenvs/piwikapi/lib/python3.6/config-3.6m-darwin'


Delete Existing Links

First, let's enter the virtualenv directory and delete off the broken links


$ rm lib/python3.6/*
$ rm include/*
$ rm .Python 


Re-virtualize


Run virtualenv again


$ virtualenv --no-site-packages -p python3.6 .
Running virtualenv with interpreter /usr/local/bin/python3.6
Using base prefix '/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6'
New python executable in /Users/hanxue/.virtualenvs/piwikapi/bin/python3.6
Not overwriting existing python script /Users/hanxue/.virtualenvs/piwikapi/bin/python (you must use /Users/hanxue/.virtualenvs/piwikapi/bin/python3.6)
Installing setuptools, pip, wheel...done.


Reinstall Packages

Even though the contents of site-packages remain the same, they have been installed for the previous version of Python. To prevent any problems, make sure you re-install them.

First, activate the virtualenv again, then look at the installed packages.


$  workon piwikapi
(piwikapi) $ pip freeze
certifi==2017.7.27.1
chardet==3.0.4
gevent==1.2.2
greenlet==0.4.12
grequests==0.3.0
idna==2.5
requests==2.18.3
urllib3==1.22


Force reinstall all the packages


(piwikapi) $ pip install --upgrade --force-reinstall certifi chardet grequests requests urllib3
Collecting certifi
  Using cached certifi-2017.7.27.1-py2.py3-none-any.whl
Collecting chardet
  Using cached chardet-3.0.4-py2.py3-none-any.whl
Collecting grequests
Collecting requests
  Using cached requests-2.18.3-py2.py3-none-any.whl
Collecting urllib3
  Using cached urllib3-1.22-py2.py3-none-any.whl
Collecting gevent (from grequests)
  Using cached gevent-1.2.2-cp36-cp36m-macosx_10_6_intel.whl
Collecting idna<2.6,>=2.5 (from requests)
  Using cached idna-2.5-py2.py3-none-any.whl
Collecting greenlet>=0.4.10 (from gevent->grequests)
Installing collected packages: certifi, chardet, idna, urllib3, requests, greenlet, gevent, grequests
  Found existing installation: certifi 2017.7.27.1
    Uninstalling certifi-2017.7.27.1:
      Successfully uninstalled certifi-2017.7.27.1
  Found existing installation: chardet 3.0.4
    Uninstalling chardet-3.0.4:
      Successfully uninstalled chardet-3.0.4
  Found existing installation: idna 2.5
    Uninstalling idna-2.5:
      Successfully uninstalled idna-2.5
  Found existing installation: urllib3 1.22
    Uninstalling urllib3-1.22:
      Successfully uninstalled urllib3-1.22
  Found existing installation: requests 2.18.3
    Uninstalling requests-2.18.3:
      Successfully uninstalled requests-2.18.3
  Found existing installation: greenlet 0.4.12
    Uninstalling greenlet-0.4.12:
      Successfully uninstalled greenlet-0.4.12
  Found existing installation: gevent 1.2.2
    Uninstalling gevent-1.2.2:
      Successfully uninstalled gevent-1.2.2
  Found existing installation: grequests 0.3.0
    Uninstalling grequests-0.3.0:
      Successfully uninstalled grequests-0.3.0
Successfully installed certifi-2017.7.27.1 chardet-3.0.4 gevent-1.2.2 greenlet-0.4.12 grequests-0.3.0 idna-2.5 requests-2.18.3 urllib3-1.22


Now your virtualenv has successfully been upgraded to the new Python version.

1 comment: