Переименование папки virtualenv, не нарушая ее

162

Я создал папку и инициализировал в ней экземпляр virtualenv.

$ mkdir myproject
$ cd myproject
$ virtualenv env

Когда я запускаю (env)$ pip freeze, он показывает установленные пакеты как следует.

Теперь я хочу переименовать myproject/в project/.

$ mv myproject/ project/

Тем не менее, теперь, когда я бегу

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

он говорит, что пип не установлен. Как переименовать папку проекта, не нарушая окружение?

Райли Уоткинс
источник
1
Этот вопрос старый и уже имеет ответ, но я должен задаться вопросом, почему ОП не может просто переместить virtualenv туда, где он был? Очевидно, что это не решает желание переместить / переименовать, но разве это не восстановит работоспособность virtualenv, или это уже безнадежно сломано?
Малик А. Руми
2
Да, вы правы, это восстановит виртуальную среду, но не решит проблему.
Флориан,
Ноябрь 2019, Python3. Лучшее решение для меня - описать в aarongorka.com/blog/portable-virtualenv
Самир Садек,

Ответы:

148

Вы должны настроить вашу установку, чтобы использовать относительные пути. virtualenvпредусматривает для этого с --relocatableопцией. Из документов :

Обычно окружения привязаны к определенному пути. Это означает, что вы не можете перемещать среду или копировать ее на другой компьютер. Вы можете исправить окружение, чтобы сделать его перемещаемым с помощью команды:

$ virtualenv - перемещаемый ENV

ПРИМЕЧАНИЕ. ENV - это имя виртуальной среды, и вы должны запускать его вне каталога ENV.

Это заставит некоторые файлы, созданные setuptools или распространять, использовать относительные пути и изменит все сценарии на использование activ_this.py вместо использования местоположения интерпретатора Python для выбора среды.

Примечание: вы должны запустить это после того, как вы установили какие-либо пакеты в среду. Если вы делаете среду перемещаемой, а затем устанавливаете новый пакет, вы должны снова запустить virtualenv --relocatable.

ire_and_curses
источник
2
предостережение: изменение env на relocatable делает больше, чем просто позволяет вам переместить папку. (см. Примечание: скопировано из документации) ... это может иметь побочные эффекты.
Бен Робертс
7
Параметр --relocatable в настоящее время имеет ряд проблем и не гарантирует работу при любых обстоятельствах. Вполне возможно, что эта опция будет устаревшей в будущей версии virtualenv. Кроме того, это не делает ваши пакеты кроссплатформенными. Вы можете перемещать каталог, но он может использоваться только на других подобных компьютерах.
Демз
1
@TheDemz grep -EIr '\Wold_venv_name\W' /path/to/new_venvпоможет найти любые шабанги, которые используют старый венв, но не является полной проверкой перемещенного венва.
варенье
2
Кроме того, вам придется отредактировать .projectфайл virtualenvwrapper , который содержит путь к исходному коду, который зависит от virtualenv, при условии, что вы используете virutalenvwrapper и также переименовали dir проекта в соответствии с новым virtualenv.
варенье
Я должен был деактивировать virtualenv, прежде чем запустить это.
антагонестам
108

Я верю, что «знать почему» важнее, чем «знать как» . Итак, вот другой подход, чтобы исправить это.

Когда вы запускаете . env/bin/activate, он фактически выполняет следующие команды (используя, /tmpнапример):

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

Тем не менее, вы только что переименовали myprojectв project, так что команда не смогла выполнить. Вот почему он говорит pip is not installed, потому что вы не установили pipв глобальную среду системы, и ваш virtualenv pipне правильно поставлен.

Если вы хотите исправить это вручную, это способ:

  1. С помощью вашего любимого редактора, такого как Vim, измените /tmp/project/env/bin/activateобычно в строке 42:

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

  2. Изменить /tmp/project/env/bin/pipв строке 1:

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

После этого envснова активируйте свою виртуальную среду , и вы увидите, что ваш pipснова вернулся.

holys
источник
6
Если необходимо вручную изменить пути, то следует отметить, что существует более двух жестко закодированных файлов. Найти их все с чем - то вроде: grep -iHnR venv-name /path/to/venv-name | grep -v "^Binary file" | grep -i venv-name. Фактически, я заметил, что в одном из моих экземпляров Django многие пакеты содержали «путь к Python sh-bang».
Кевин
Это мне очень помогло. Я определенно должен был знать почему ... Спасибо!
Джарвис
В отличие от приведенного выше комментария Кевена, я считаю, что редактирование этих двух строк решает для меня все проблемы, связанные с перемещением virtualenv. Возможно, есть какой-то вариант использования, которым я не пользуюсь, и поэтому не сталкиваюсь с проблемой.
Deleet
Сотрите это! Сегодня я столкнулся с проблемой: ipython не будет работать в virtualenv. Чтобы решить эту проблему, я отредактировал заголовок bash (как он называется?) В ipythonфайле, и тогда он работал нормально.
Deleet
Хм, это не работает для меня, и кажется, что мой сценарий активации не имеет строки 1, которая упоминается здесь в шаге 2. Что-то изменилось?
Эван Замир
40

ПРИМЕЧАНИЕ: как @jb. указывает, что это решение применимо только к легко (повторно) создан virtualenvs. Если для установки этого решения требуется несколько часов, не рекомендуется


Virtualenvs великолепны, потому что их легко создавать и переключать; они мешают вам попасть в одну конфигурацию. Если вы знаете требования проекта или можете их получить, сделайте новоеvirtualenv :

  • Создать requirements.txtфайл

    (env)$ pip freeze > requirements.txt

    • Если вы не можете создать requirements.txtфайл, проверьте env/lib/pythonX.X/site-packagesперед удалением оригинала env.
  • Удалить существующий (env)

    deactivate && rm -rf env

  • Создайте новый virtualenv, активируйте его и установите требования

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


Кроме того, используйте virtualenvwrapper, чтобы сделать вещи немного проще, поскольку все virtualenv хранятся в централизованном месте.

$(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
bnjmn
источник
6
Ну, для некоторых людей это pip install -r requirements.txtзанимает пару часов (сборка сторонних C-расширений на Raspberry Pi).
JB.
4
Возможно, это правда, но мне кажется, что это крайний случай. Я все еще думаю, что это может быть жизнеспособным решением для многих случаев.
bnjmn
Да, многие проекты (например, веб-сайт Django) занимают всего 30 секунд, чтобы установить все, даже если у них есть пара дюжин зависимостей (при условии, что вы сначала загружаете все и используете '--no-index --find-links = downloadDir' )
Джонатан Хартли
1
@bnjmn однострочник virtualenv env && pip install -r requirements.txtНЕ установит требования в новой среде, потому что вы не активируете его
Yarin
1
@Yarin Спасибо за указание на это. Я полностью пропустил это, будучи virtualenv-wrapperсамим пользователем (который автоматически активируется при создании). Я обновил свой ответ, чтобы включить активацию virtualenvв надежде избежать любой путаницы.
Bnjmn
28

Я всегда устанавливаю virtualenvwrapper, чтобы выручить. Из командной строки:

pip install virtualenvwrapper

Есть способ, описанный в документах virtualenvwrapper - cpvirtualenv Это то, что вы делаете. Убедитесь, что вы находитесь вне своей среды и вернетесь к приглашению оболочки. Введите это с необходимыми именами:

cpvirtualenv oldenv newenv

И затем, если необходимо:

rmvirtualenv oldenv

Чтобы перейти к вашему newenv:

workon newenv
Afrowave
источник
1
Ответ от Аферы действительно должен быть принятым методом.
Jaxian
Это работает только если кто-то использует virtualenvwrapper, а не только virtualenv. Этот ответ от @ryankdwyer лучше.
LS
Я отредактировал свой ответ, чтобы отразить, что нужно установить «virtualenvwrapper». Предполагая, что переименование виртуальных сред происходит много раз, я бы порекомендовал этот способ.
Афгас
Несмотря на то, что это зависит от virtualenvwrapper, это самый простой. И это хорошо работает.
Блазродри
17

Вы можете исправить вашу проблему, выполнив следующие действия:

  1. переименуйте ваш каталог
  2. повторите это: $ virtualenv ..\path\renamed_directory
  3. virtualenv исправит ассоциации каталогов, оставив ваши пакеты на месте
  4. $ scripts/activate
  5. $ pip freeze чтобы убедиться, что ваши пакеты на месте
  6. Важная оговорка: если у вас есть какие-либо статические зависимости пути в файлах сценариев в вашем каталоге virtualenv, вам придется их вручную изменить.
ryankdwyer
источник
1
Это было очень хорошее решение для меня. Поскольку это решение может избежать некоторых проблем, связанных с --relocatable, я думаю, что это решение лучше, чем принятый ответ. До сих пор я заметил, что многие .pycфайлы _new_name_/lib/python2.7все еще ссылаются на _old_name_. Однако это, похоже, не влияет на то, как работает моя среда. Возможно, единственным лучшим решением является использование virtualenvwrapperили некоторые другие утилиты, упомянутые в ответах здесь. По крайней мере, это решение не требует установки дополнительных программ.
LS
Работает как шарм!
Амир Хоссейн
13

Еще один способ сделать это, который работал для меня много раз без проблем, является virtualenv-clone :

pip install virtualenv-clone
virtualenv-clone old-dir/env new-dir/env
Энтони Хэтчкинс
источник
Это должно быть помечено как лучший ответ. Руки вниз! Клонирование заняло некоторое время, так что наберитесь терпения, ребята.
Амитраджит Бозе
Virtualenv-клон пренебрегает обновлением подсказки. Пришлось сделать это вручную. Кроме этого, это здорово.
user3667349
5

(внутри папки проекта)

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

Не забудьте деактивировать и активировать

Ignacio
источник
Работает хорошо; Или для пути Linux:sed -i "s|$old_dir|$new_dir|g" bin/*
Destroyica
sed -i '.original' 's/old_dir_name/new_dir_name/g' *для Макса
Алекс
1

virtualenv --relocatable ENVэто не желаемое решение. Я предполагаю, что большинство людей хотят иметь возможность переименовать virtualenv без каких-либо долгосрочных побочных эффектов.

Поэтому я создал простой инструмент для этого. Страница проекта для virtualenv-mv описывает ее более подробно, но, по сути, вы можете использовать ее так virtualenv-mvже, как если бы вы использовали простую реализацию mv(без каких-либо опций).

Например:

virtualenv-mv myproject project

Обратите внимание, однако, что я только что взломал это. Он может сломаться при необычных обстоятельствах (например, символические ссылки virtualenvs), поэтому, пожалуйста, будьте осторожны (сделайте резервную копию того, что вы не можете позволить себе потерять) и дайте мне знать, если у вас возникнут какие-либо проблемы.

Шесть
источник