Can I move a virtualenv?

Posted on

Question :

Can I move a virtualenv?

This question is not a duplicate.

It pertains not just to renaming a virtual environment, but to actually moving it to a different directory, including, potentially, a different user’s directory.

This is not the same as merely renaming a virtual environment, especially to people unfamiliar with virtualenvs.

If I create a virtualenv, and I move it to a different folder, will it still work?

$ virtualenv -p /usr/bin/python3 /home/me/Env/my-python-venv
$ source Env/my-python-venv/bin/activate
(my-python-venv) $ 

…later that day, the virtual environment MOVED…

(my-python-venv) $ deactivate
$ mkdir -p /home/me/PeskyPartyPEnvs
$ mv /home/me/Env/my-python-venv /home/me/PeskyPartyPEnvs/

Question:

Will this work?

$ source /home/me/PeskyPartyPEnvs/my-python-venv/bin/activate
(my-python-venv) $ /home/me/PeskyPartyPEnvs/my-python-venv/bin/pip3 install foaas

I mean this as less of a question about the wisdom of trying this (unless that wisdom is humorous, of course), and more about whether it’s possible. I really want to know whether it’s possible to do in Python 3, or whether I just have to suck it up and clone it.

Can I just mv a virtualenv like that without sadness? I do want to avoid sadness.

Answer #1:

Yes. It is possible to move it on the same platform. You can use --relocatable on an existing environment.

From --help:

–relocatable — Make an EXISTING virtualenv environment relocatable.
This fixes up scripts and makes all .pth files relative.

HOWEVER, this does NOT seem to change the activate script, and rather only changes the pip* and easy_install* scripts. In the activate script, the $VIRTUAL_ENV environment variable hardcoded as the original /path/to/original/venv. The $VIRTUAL_ENV variable is used to set the PATH of your active environment too, so it must be changed based on the new location in order to call python and pip etc. without absolute path.

To fix this issue, you can change the $VIRTUAL_ENV environment variable in the activate script (for example using sed), and everything should be good to go.

An example of usage:

$ cd ~/first
$ virtualenv my-venv
$ grep 'VIRTUAL_ENV=' my-venv/bin/activate
VIRTUAL_ENV="/home/username/first/my-venv"
$ virtualenv --relocatable my-venv
Making script my-venv/bin/easy_install relative
Making script my-venv/bin/easy_install-2.7 relative
Making script my-venv/bin/pip relative
Making script my-venv/bin/pip2 relative
Making script my-venv/bin/pip2.7 relative
### Note that `activate` has not been touched
$ mkdir ~/second
$ mv my-venv ~/second
$ cd ~/second
$ grep 'VIRTUAL_ENV=' my-venv/bin/activate
VIRTUAL_ENV=/home/username/first/my-venv
### (This variable hasn't been changed, it still refers to the old, now non-existent directory!)
$ sed -i -e 's|username/first|username/second|' my-venv/bin/activate
## sed can be used to change the path.
## Note that the `-i` (in place) flag won't work on all machines. 
$ source my-venv/bin/activate 
(my-venv) $ pip install foass
...
(my-venv) $ python 
[...]
> import foass

Hooray, now you can install things and load them into your newly located virtual environment.

Answered By: Nathan Basanese

Answer #2:

For Python 3.3+ (with new venv built-in module)

Short Answer (regardless of version):

  • There’s no clean, direct way to move a virtual environment
  • Just recreate, it’s easy!!


Long Answer:

As of Python v3.3, virtualenv has become a built-in module named venv.

The --relocatable option mentioned in other answers has not been included in venv, and currently there is no good, safe way that I’m aware of to either rename or relocate a Python virtual environment.

However, there is a fairly simple way to simply recreate a virtual environment, with all its current installed packages. See this answer, or see the section below for information on recreating a virtual environment. During the process you can recreate the new environment in whatever location and with whatever name you desire. Or see the section below for the process.

In that answer, he does mention a few other 3rd party packages which may support direct renames or moves. If you are settled on pursuing a way to move a virtual environment intact, you could look into if those work with venv as well.

Note: In that answer, it is focused on virtualenv, rather than venv. See below for how to translate.


venv vs. older virtualenv command syntax

The command to use venv is:

python -m venv

rather than just virtualenv, which installs as a command in the original package. Where “python” refers to however you run your python executable, which could be a variety of things, such as:

  1. python
  2. py or py -3.7 or similar (the Python Launcher for Windows for Python 3.3+ and Windows only at the moment)
  3. python3 (convention for linux environments that dual install python 2 and 3)
  4. If you are having issues, use the absolute path to the python executable you want to run: e.g. c:program filespython37python.exe

If you are unsure which version is being run, you can always python --version to find out.


How to recreate a virtual environment

Creating/recreating a virtual environment is easy and should become second nature after you work with them for a bit. This process mirrors what you would do to distribute your script as a package (with it’s dependencies) in the first half, and then what someone would do to install your script/package for further development.

First, get an updated list of what is in the virtual environment. With it active, get the Python version it uses and save out the list of dependencies to a file.

  1. Use python --version with the virtual environment activated to see what version of Python it is using.

    • This is for clarity – you may want to update the Python version for various reasons – at least to the latest patch version
    • For example, if the existing venv is using Python v3.7.4, but now v3.7.6 is out – use v3.7.6 instead, which should including only non-breaking security and bug fixes.
  2. Use python -m pip freeze > requirements.txt to create the list of current package dependencies and put them into the requirements.txt file. This command works in Linux or the Git Bash for sure – not 100% sure about Powershell or Command Line in Windows.

Now create a new virtual environment and then add the dependencies from the old one.

  1. Make your new venv.

    • Make sure you are using the correct version of python that you want to install to the venv.
    • If you want it to be exactly the same Python version:
      • Run python directly from the current virtual environment (with it activated), and just use python as the command
      • Or use an absolute path with python.exe in the virtual environment folder
    • For the new venv folder entry in the command:
      • Either add an absolute or relative path to the desired final folder location.
      • Use python -m venv my_new_venv to create a new virtual environment in the current working directory in a new my_new_venv folder.
      • The name of the venv folder will be the name of the venv (what shows up in the prompt when it is activated).
  2. Install your dependencies from the requirements.txt file.

    • python -m pip install -r requirements.txt

You might need to reinstall local packages that are in development mode.

Note, if you ever need to see the specific location a package is installed to, use:

  • python -m pip list -v
  • The -v or “verbose” option will add some extra information about each package that is installed, including the path it is installed in. This is useful to make sure you are keeping virtual, user, and system installed packages straight.

At this point you can just delete the old venv folder and all contents. I recommend using a GUI for that – file deletions are often permanent from the linux command line, and a small typo can be bad news.

Answered By: hilcharge

Answer #3:

The --relocatable argument to virtualenv appears to allow you to do this.

Answered By: LightCC

Answer #4:

BUT ALAS:

No, you can’t simply mv. There are workarounds, but it might be easier to reinstall.

(my-python-venv)$ /home/me/PeskyPartyPEnvs/pip3 install foaas
zsh: /home/me/PeskyPartyPEnvs/pip3: bad interpreter: /home/me/Env/my-python-venv/bin/python3: no such file or directory
(my-python-venv)$ deactivate
$ 

… presses enter a lot in frustration, and the following works

$
$
$ pip3 search foaas

Except it is not from my-python-venv, ergo sadness.

Want to mv your virtualenv and use it, otherwise unmodified?

Short Answer:

I'll let Boromir say it, so he can make it clear:

Well, ya can’t.

Answered By: Ruth Franklin

Answer #5:

Yes, this should be possible if you haven’t done anything that depends on the current directory of the virtualenv.

However, if you have the choice, the best thing to do is to create new virtualenv and start using the new virtualenv instead. This is the safest choice and least likely to cause issues later.

The documentation does mention that:

Each virtualenv has path information hard-coded into it,

For example, if you have run setvirtualenvproject then it won’t be able to switch to the right directory after you run workon ... so in that case you’d need to fix that manually.

In general a virtualenv is little more than a directory with the necessary Python interpreter files plus packages that you need.

Answered By: Nathan Basanese

Answer #6:

Using answers of this and other threads about similar topic, I’ve made a bash script that, located and executed within the virtualenv directory itself, will help with your virtualenv moves.

After doing virtualenv --relocatable yourenv you’ll need to change your VIRTUAL_ENV variable every time you move the directory, so if you don’t wan’t to change it manually, use this.

#!/bin/bash n 
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
EXISTING=$(grep 'VIRTUAL_ENV=' bin/activate)
NEWDIR=VIRTUAL_ENV="$DIR"

Leave a Reply

Your email address will not be published.