167

I've created folder and initialized a virtualenv instance in it.

$ mkdir myproject
$ cd myproject
$ virtualenv env

When I run (env)$ pip freeze, it shows the installed packages as it should.

Now I want to rename myproject/ to project/.

$ mv myproject/ project/

However, now when I run

$ . env/bin/activate
(env)$ pip freeze

it says pip is not installed. How do I rename the project folder without breaking the environment?

Riley Watkins
  • 3,043
  • 2
  • 24
  • 17
  • 1
    This question is old and already has an answer, but I have to wonder, why couldn't the OP just move the virtualenv back to where it was? Obviously that doesn't solve the desire to move / rename, but wouldn't that restore a working virtualenv, or is it already hopelessly broken? – Malik A. Rumi May 28 '16 at 21:06
  • 2
    Yes, you are right, it would repair the virtual env, but not solve the issue. – Florian Feb 06 '17 at 10:20
  • November 2019, Python3. The best solution for me is describe in https://aarongorka.com/blog/portable-virtualenv/ – Samir Sadek Dec 05 '19 at 17:39

12 Answers12

149

You need to adjust your install to use relative paths. virtualenv provides for this with the --relocatable option. From the docs:

Normally environments are tied to a specific path. That means that you cannot move an environment around or copy it to another computer. You can fix up an environment to make it relocatable with the command:

$ virtualenv --relocatable ENV

NOTE: ENV is the name of the virtual environment and you must run this from outside the ENV directory.

This will make some of the files created by setuptools or distribute use relative paths, and will change all the scripts to use activate_this.py instead of using the location of the Python interpreter to select the environment.

Note: you must run this after you've installed any packages into the environment. If you make an environment relocatable, then install a new package, you must run virtualenv --relocatable again.

Gourav Chawla
  • 332
  • 1
  • 2
  • 11
ire_and_curses
  • 64,177
  • 22
  • 110
  • 139
  • 2
    caveat: Changing an env to relocatable does more than just let you move the folder. (see the *Note:* copied from the docs)... it may have side effects. – B Robster Sep 17 '12 at 11:59
  • 8
    The --relocatable option currently has a number of issues, and is not guaranteed to work in all circumstances. It is possible that the option will be deprecated in a future version of virtualenv. Also, this does not make your packages cross-platform. You can move the directory around, but it can only be used on other similar computers. – The Demz Aug 15 '13 at 11:33
  • 1
    @TheDemz `grep -EIr '\Wold_venv_name\W' /path/to/new_venv` will help find any shabangs that use the old venv, but is not a complete verifcation of the relocated venv. – hobs Oct 10 '13 at 16:31
  • 2
    Also, you'll have to edit the virtualenvwrapper `.project` file, which contains the path to the source code that depends on the virtualenv, assuming you are using virutalenvwrapper and have also renamed the project dir to match the new virtualenv. – hobs Oct 10 '13 at 16:50
  • I had to deactivate the virtualenv before running this. – antonagestam Oct 31 '13 at 09:27
  • This feature is now deprecated. This answer is no longer valid. – dmbarbour Apr 29 '20 at 19:13
119

I believe "knowing why" matters more than "knowing how". So, here is another approach to fix this.

When you run . env/bin/activate, it actually executes the following commands (using /tmp for example):

VIRTUAL_ENV="/tmp/myproject/env"
export VIRTUAL_ENV

However, you have just renamed myproject to project, so that command failed to execute. That is why it says pip is not installed, because you haven't installed pip in the system global environment and your virtualenv pip is not sourced correctly.

If you want to fix this manually, this is the way:

  1. With your favorite editor like Vim, modify /tmp/project/env/bin/activate usually in line 42:

    VIRTUAL_ENV='/tmp/myproject/env' => VIRTUAL_ENV='/tmp/project/env'

  2. Modify /tmp/project/env/bin/pip in line 1:

    #!/tmp/myproject/env/bin/python => #!/tmp/project/env/bin/python

After that, activate your virtual environment env again, and you will see your pip has come back again.

wjandrea
  • 16,334
  • 5
  • 30
  • 53
holys
  • 11,255
  • 12
  • 40
  • 50
  • 8
    If manually changing the paths is desired, then it should be noted that there are more than two hard-coded files. Find them all with something like: `grep -iHnR venv-name /path/to/venv-name | grep -v "^Binary file" | grep -i venv-name`. In fact, I noticed that in one of my Django instances, a lot of the packages had the "path to Python sh-bang" in them. – Kevin May 23 '16 at 14:01
  • This helped me a lot. I definitely needed to know why... Thanks! – Jarvis Jul 20 '16 at 04:38
  • 1
    In contrast to Keven's comment above, I find that editing these two lines solves all problems for me with regards to moving `virtualenv`'s. Perhaps there's some use case that I'm not using and so don't encounter the problem. – CoderGuy123 Nov 04 '16 at 18:06
  • Scratch that! Today I ran into a problem: ipython would not work within the `virtualenv`. To solve it, I edited the bash header (what is it called?) in the `ipython` file and then it worked fine. – CoderGuy123 Nov 04 '16 at 20:22
  • 1
    Hmm this is not working for me, and it seems my activate script does not have the Line 1 that is referred to here in Step 2. Did something change? – Evan Zamir Jan 11 '18 at 22:31
  • Wouldn't this entire problem be eliminated by setting `VIRTUAL_ENV=\`pwd\`` ? – Homunculus Reticulli Aug 17 '18 at 13:02
  • @Homunculus No. Think about what would happen if you activated the virtualenv from another directory. – wjandrea May 04 '19 at 20:25
  • Thanks, saved my day! – Obnebion May 26 '21 at 14:06
40

NOTE: As @jb. points out, this solution only applies to easily (re)created virtualenvs. If an environment takes several hours to install this solution is not recommended


Virtualenvs are great because they are easy to make and switch around; they keep you from getting locked into a single configuration. If you know the project requirements, or can get them, Make a new virtualenv:

  • Create a requirements.txt file

    (env)$ pip freeze > requirements.txt

    • If you can't create the requirements.txt file, check env/lib/pythonX.X/site-packages before removing the original env.
  • Delete the existing (env)

    deactivate && rm -rf env

  • Create a new virtualenv, activate it, and install requirements

    virtualenv env && . env/bin/activate && pip install -r requirements.txt


Alternatively, use virtualenvwrapper to make things a little easier as all virtualenvs are kept in a centralized location

$(old-venv) pip freeze > temp-reqs.txt
$(old-venv) deactivate
$ mkvirtualenv new-venv
$(new-venv) pip install -r temp-reqs.txt
$(new-venv) rmvirtualenv old-venv
ThiefMaster
  • 285,213
  • 77
  • 557
  • 610
bnjmn
  • 4,162
  • 4
  • 32
  • 49
  • 6
    Well for some people `pip install -r requirements.txt` takes couple of hours (compiling third party C-extensions on raspberry pi). – jb. Nov 17 '13 at 22:35
  • 5
    Perhaps true, but that seems like an edge-case to me. I still think this may be a viable solution for many cases. – bnjmn Dec 04 '13 at 20:47
  • Yah, many projects (Django website, for example) only take 30 seconds to install everything, even if they have a couple of dozen dependencies (provided you download everything first and use '--no-index --find-links=downloadDir') – Jonathan Hartley Apr 11 '14 at 21:03
  • To delete a python virtual environment I suggest using rmvirtualenv. – Sandeep May 16 '14 at 13:26
  • Good point. That's how I do it. I think that's covered in the second part of the answer. It seemed the OP wasn't using `virtualenvwrapper` so the main answer is only focused on `virtualenv` – bnjmn May 16 '14 at 13:29
  • 1
    @bnjmn the one-liner `virtualenv env && pip install -r requirements.txt` will NOT install the requirements in the new environment because you don't activate it – Yarin Dec 30 '14 at 17:36
  • 1
    @Yarin Thanks for pointing that out. I totally missed it, being `virtualenv-wrapper` user myself (which auto activates on creation). I've update my answer to include activating the `virtualenv` in hopes of avoiding any confusion. – bnjmn Dec 30 '14 at 20:21
  • This answer has nothing to do with the origin question: how to move the venv dir without breaking it – Reorx Nov 05 '20 at 12:15
29

I always install virtualenvwrapper to help out. From the shell prompt:

pip install virtualenvwrapper

There is a way documented in the virtualenvwrapper documents - cpvirtualenv This is what you do. Make sure you are out of your environment and back to the shell prompt. Type in this with the names required:

cpvirtualenv oldenv newenv

And then, if necessary:

rmvirtualenv oldenv

To go to your newenv:

workon newenv
Afrowave
  • 841
  • 9
  • 21
  • 1
    Afrowave's answer really should be the accepted method. – Jaxian Jul 25 '16 at 17:38
  • This only works if one is using `virtualenvwrapper`, not just `virtualenv`. [This answer](http://stackoverflow.com/a/29482481/543738) from @ryankdwyer is better. – Mr. Lance E Sloan Aug 19 '16 at 17:57
  • I edited my answer to reflect that one should install 'virtualenvwrapper'. Assuming that the renaming virtual environments happens a lot, I would recommend this way. – Afrowave Aug 29 '16 at 14:13
  • Even though it relies on virtualenvwrapper, it is the simplest one. And it works well. – blasrodri Feb 21 '17 at 08:03
17

You can fix your issue by following these steps:

  1. rename your directory
  2. rerun this: $ virtualenv ..\path\renamed_directory
  3. virtualenv will correct the directory associations while leaving your packages in place
  4. $ scripts/activate
  5. $ pip freeze to verify your packages are in place
  6. An important caveat, if you have any static path dependencies in script files in your virtualenv directory, you will have to manually change those.
ryankdwyer
  • 603
  • 7
  • 14
  • 1
    This was a very good solution for me. Since this solution _may_ avoid some of the problems associated with `--relocatable`, I think this solution is better than the accepted answer. So far, I've noticed that many `.pyc` files in `_new_name_/lib/python2.7` still refer to `_old_name_`. However, that doesn't seem to affect how my environment works. Maybe the only better solution is using `virtualenvwrapper` or some of the other utilities mentioned among the answers here. At least this solution doesn't require installing additional programs. – Mr. Lance E Sloan Aug 19 '16 at 18:15
  • Works like a charm! – AmirHossein Jul 22 '17 at 06:49
13

Yet another way to do it that worked for me many times without problems is virtualenv-clone:

pip install virtualenv-clone
virtualenv-clone old-dir/env new-dir/env
Antony Hatchkins
  • 25,545
  • 8
  • 96
  • 98
7

Run this inside your project folder:

cd bin
sed -i 's/old_dir_name/new_dir_name/g' *

Don't forget to deactivate and activate.

meager
  • 209,754
  • 38
  • 307
  • 315
Ignacio
  • 185
  • 1
  • 11
1

virtualenv --relocatable ENV is not a desirable solution. I assume most people want the ability to rename a virtualenv without any long-term side effects.

So I've created a simple tool to do just that. The project page for virtualenv-mv outlines it in a bit more detail, but essentially you can use virtualenv-mv just like you'd use a simple implementation of mv (without any options).

For example:

virtualenv-mv myproject project

Please note however that I just hacked this up. It could break under unusual circumstances (e.g. symlinked virtualenvs) so please be careful (back up what you can't afford to lose) and let me know if you encounter any problems.

Six
  • 3,909
  • 3
  • 21
  • 34
1

In Python 3.3+ with built-in venv

As of Python 3.3 the virtualenv package is now built-in to Python as the venv module. There are a few minor differences, one of which is the --relocatable option has been removed. As a result, it is normally best to recreate a virtual environment rather than attempt to move it. See this answer for more information on how to do that.

What is the purpose behind wanting to move rather than just recreate any virtual environment? A virtual environment is intended to manage the dependencies of a module/package with the venv so that it can have different and specific versions of a given package or module it is dependent on, and allow a location for those things to be installed locally.

As a result, a package should provide a way to recreate the venv from scratch. Typically this is done with a requirements.txt file and sometimes also a requirements-dev.txt file, and even a script to recreate the venv in the setup/install of the package itself.

One part that may give headaches is that you may need a particular version of Python as the executable, which is difficult to automate, if not already present. However, when recreating an existing virtual environment, one can simply run python from the existing venv when creating the new one. After that it is typically just a matter of using pip to reinstall all dependencies from the requirements.txt file:

From Git Bash on Windows:

python -m venv mynewvenv
source myvenv/Scripts/activate
pip install -r requirements.txt

It can get a bit more involved if you have several local dependencies from other locally developed packages, because you may need to update local absolute paths, etc. - though if you set them up as proper Python packages, you can install from a git repo, and thus avoid this issue by having a static URL as the source.

LightCC
  • 5,446
  • 2
  • 28
  • 67
0

Even easier solution which worked for me: just copy the site-packages folder of your old virtual environment into a new one.

Niels
  • 613
  • 9
  • 10
0

Using Visual Studio Code (vscode), I just opened the ./env folder in my project root, and did a bulk find/replace to switch to my updated project name. This resolved the issue.

Confirm with which python

0

If you are using an conda env,

conda create --name new_name --clone old_name
conda remove --name old_name --all # or its alias: `conda env remove --name old_name`
Shrm
  • 157
  • 1
  • 5