Renommer un dossier virtualenv sans le casser

162

J'ai créé un dossier et y ai initialisé une instance virtualenv.

$ mkdir myproject
$ cd myproject
$ virtualenv env

Lorsque je cours (env)$ pip freeze, il affiche les packages installés comme il se doit.

Maintenant, je veux renommer myproject/en project/.

$ mv myproject/ project/

Cependant, maintenant quand je cours

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

il dit que pip n'est pas installé. Comment renommer le dossier du projet sans interrompre l'environnement?

Riley Watkins
la source
1
Cette question est ancienne et a déjà une réponse, mais je me demande pourquoi l'OP ne pourrait-il pas simplement déplacer le virtualenv là où il était? Évidemment, cela ne résout pas le désir de déplacer / renommer, mais cela ne restaurerait-il pas un virtualenv fonctionnel, ou est-il déjà désespérément cassé?
Malik A. Rumi
2
Oui, vous avez raison, cela réparerait l'environnement virtuel, mais ne résoudrait pas le problème.
Florian
Novembre 2019, Python3. La meilleure solution pour moi est de décrire dans aarongorka.com/blog/portable-virtualenv
Samir Sadek

Réponses:

148

Vous devez ajuster votre installation pour utiliser des chemins relatifs. virtualenvprévoit cela avec l' --relocatableoption. À partir de la documentation :

Normalement, les environnements sont liés à un chemin spécifique. Cela signifie que vous ne pouvez pas déplacer un environnement ou le copier sur un autre ordinateur. Vous pouvez réparer un environnement pour le rendre relocalisable avec la commande:

$ virtualenv - ENV relocalisable

REMARQUE: ENV est le nom de l'environnement virtuel et vous devez l'exécuter depuis l'extérieur du répertoire ENV.

Cela rendra certains des fichiers créés par setuptools ou distribuera des chemins relatifs, et changera tous les scripts pour utiliser activate_this.py au lieu d'utiliser l'emplacement de l'interpréteur Python pour sélectionner l'environnement.

Remarque: vous devez l'exécuter après avoir installé les packages dans l'environnement. Si vous rendez un environnement déplaçable, puis installez un nouveau package, vous devez réexécuter virtualenv --relocatable.

ire_and_curses
la source
2
mise en garde: changer un env en déplaçable ne vous permet pas seulement de déplacer le dossier. (voir la note: copié à partir de la documentation) ... cela peut avoir des effets secondaires.
Ben Roberts
7
L'option --relocatable présente actuellement un certain nombre de problèmes et n'est pas garantie de fonctionner dans toutes les circonstances. Il est possible que l'option soit obsolète dans une future version de virtualenv. De plus, cela ne rend pas vos packages multiplateformes. Vous pouvez déplacer le répertoire, mais il ne peut être utilisé que sur d'autres ordinateurs similaires.
The Demz
1
@TheDemz vous grep -EIr '\Wold_venv_name\W' /path/to/new_venvaidera à trouver tous les shabangs qui utilisent l'ancien venv, mais ne constitue pas une vérification complète du venv déplacé.
plaques de cuisson
2
De plus, vous devrez modifier le .projectfichier virtualenvwrapper , qui contient le chemin d'accès au code source qui dépend du virtualenv, en supposant que vous utilisez virutalenvwrapper et que vous avez également renommé le répertoire du projet pour correspondre au nouveau virtualenv.
plaques de cuisson
J'ai dû désactiver le virtualenv avant de l'exécuter.
antonagestam
108

Je crois que "savoir pourquoi" compte plus que "savoir comment" . Alors, voici une autre approche pour résoudre ce problème.

Lorsque vous exécutez . env/bin/activate, il exécute en fait les commandes suivantes (en utilisant /tmppar exemple):

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

Cependant, vous venez de renommer myprojecten project, de sorte que la commande n'a pas pu s'exécuter. C'est pourquoi il est dit pip is not installed, parce que vous ne l'avez pas installé pipdans l'environnement global du système et que votre virtualenv pipne provient pas correctement.

Si vous souhaitez résoudre ce problème manuellement, procédez comme suit:

  1. Avec votre éditeur préféré comme Vim, modifiez /tmp/project/env/bin/activategénéralement à la ligne 42:

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

  2. Modifier /tmp/project/env/bin/pipà la ligne 1:

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

Après cela, activez à nouveau votre environnement virtuel envet vous verrez votre pipretour.

holys
la source
6
Si vous souhaitez modifier manuellement les chemins, il convient de noter qu'il existe plus de deux fichiers codés en dur. Trouvez -les tous avec quelque chose comme: grep -iHnR venv-name /path/to/venv-name | grep -v "^Binary file" | grep -i venv-name. En fait, j'ai remarqué que dans l'une de mes instances Django, beaucoup de paquets contenaient le "chemin vers Python sh-bang".
Kevin
Cela m'a beaucoup aidé. J'avais vraiment besoin de savoir pourquoi ... Merci!
Jarvis
Contrairement au commentaire de Keven ci-dessus, je trouve que l'édition de ces deux lignes résout tous les problèmes pour moi en ce qui concerne les déplacements virtualenv. Il y a peut-être un cas d'utilisation que je n'utilise pas et que je ne rencontre donc pas le problème.
Supprimer
Grattez ça! Aujourd'hui, j'ai rencontré un problème: ipython ne fonctionnerait pas avec le virtualenv. Pour le résoudre, j'ai édité l'en-tête bash (comment s'appelle-t-il?) Dans le ipythonfichier, puis cela a bien fonctionné.
Supprimer
Hmm cela ne fonctionne pas pour moi, et il semble que mon script d'activation n'ait pas la ligne 1 mentionnée ici à l'étape 2. Quelque chose a-t-il changé?
Evan Zamir
40

REMARQUE: comme @jb. souligne que cette solution ne s'applique qu'aux (re) créations faciles virtualenv. Si un environnement prend plusieurs heures pour installer cette solution n'est pas recommandée


Les Virtualenvs sont excellents car ils sont faciles à créer et à changer; ils vous empêchent de vous enfermer dans une seule configuration. Si vous connaissez les exigences du projet ou pouvez les obtenir, créez un nouveauvirtualenv :

  • Créer un requirements.txtfichier

    (env)$ pip freeze > requirements.txt

    • Si vous ne pouvez pas créer le requirements.txtfichier, vérifiez env/lib/pythonX.X/site-packagesavant de supprimer l'original env.
  • Supprimer l'existant (env)

    deactivate && rm -rf env

  • Créez-en un nouveau virtualenv, activez-le et installez les exigences

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


Vous pouvez également utiliser virtualenvwrapper pour rendre les choses un peu plus faciles car toutes les virtualenv sont conservées dans un emplacement centralisé

$(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
la source
6
Eh bien, pour certaines personnes, cela pip install -r requirements.txtprend quelques heures (la compilation d'extensions C tierces sur raspberry pi).
jb.
4
Peut-être vrai, mais cela me semble être un cas critique. Je pense toujours que cela peut être une solution viable dans de nombreux cas.
bnjmn
Oui, de nombreux projets (le site Web de Django, par exemple) ne prennent que 30 secondes pour tout installer, même s'ils ont une douzaine de dépendances (à condition que vous téléchargiez tout d'abord et que vous utilisiez '--no-index --find-links = downloadDir' )
Jonathan Hartley
1
@bnjmn le one-liner virtualenv env && pip install -r requirements.txtn'installera PAS les exigences dans le nouvel environnement car vous ne l'activez pas
Yarin
1
@Yarin Merci d'avoir signalé cela. Je l'ai totalement manqué, étant virtualenv-wrappermoi-même utilisateur (qui s'active automatiquement à la création). J'ai mis à jour ma réponse pour inclure l'activation du virtualenvdans l'espoir d'éviter toute confusion.
bnjmn
28

J'installe toujours virtualenvwrapper pour m'aider. À partir de l'invite du shell:

pip install virtualenvwrapper

Il existe une méthode documentée dans les documents de virtualenvwrapper - cpvirtualenv C'est ce que vous faites. Assurez-vous que vous êtes hors de votre environnement et revenez à l'invite du shell. Tapez ceci avec les noms requis:

cpvirtualenv oldenv newenv

Et puis, si nécessaire:

rmvirtualenv oldenv

Pour accéder à votre newenv:

workon newenv
Afrowave
la source
1
La réponse d'Afrowave devrait vraiment être la méthode acceptée.
Jaxian
Cela ne fonctionne que si l'on utilise virtualenvwrapper, pas seulement virtualenv. Cette réponse de @ryankdwyer est meilleure.
LS
J'ai édité ma réponse pour refléter qu'il faut installer «virtualenvwrapper». En supposant que le changement de nom des environnements virtuels se produit souvent, je recommanderais cette méthode.
Afrowave
Même s'il repose sur virtualenvwrapper, c'est le plus simple. Et ça marche bien.
blasrodri
17

Vous pouvez résoudre votre problème en suivant ces étapes:

  1. renommer votre répertoire
  2. réexécutez ceci: $ virtualenv ..\path\renamed_directory
  3. virtualenv corrigera les associations de répertoires tout en laissant vos packages en place
  4. $ scripts/activate
  5. $ pip freeze pour vérifier que vos packages sont en place
  6. Une mise en garde importante, si vous avez des dépendances de chemin statiques dans les fichiers de script de votre répertoire virtualenv, vous devrez les modifier manuellement.
ryankdwyer
la source
1
C'était une très bonne solution pour moi. Étant donné que cette solution peut éviter certains des problèmes associés --relocatable, je pense que cette solution est meilleure que la réponse acceptée. Jusqu'à présent, j'ai remarqué que de nombreux .pycfichiers _new_name_/lib/python2.7font toujours référence _old_name_. Cependant, cela ne semble pas affecter le fonctionnement de mon environnement. Peut-être que la seule meilleure solution consiste à utiliser virtualenvwrapperou à certains des autres utilitaires mentionnés parmi les réponses ici. Au moins, cette solution ne nécessite pas l'installation de programmes supplémentaires.
LS
Fonctionne comme un charme!
AmirHossein
13

Une autre façon de le faire qui a fonctionné pour moi plusieurs fois sans problème est virtualenv-clone :

pip install virtualenv-clone
virtualenv-clone old-dir/env new-dir/env
Antony Hatchkins
la source
Cela devrait être marqué comme la meilleure réponse. Les doigts dans le nez! Il a fallu du temps pour cloner, alors soyez patient.
Amitrajit Bose
virtualenv-clone néglige de mettre à jour l'invite. J'ai dû y aller manuellement. A part ça, c'est super.
user3667349
5

(dans le dossier du projet)

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

N'oubliez pas de désactiver et d'activer

Ignacio
la source
Fonctionne bien; Ou pour le chemin Linux:sed -i "s|$old_dir|$new_dir|g" bin/*
Destroyica
sed -i '.original' 's/old_dir_name/new_dir_name/g' *pour macs
Alex
1

virtualenv --relocatable ENVn'est pas une solution souhaitable. Je suppose que la plupart des gens veulent pouvoir renommer un virtualenv sans aucun effet secondaire à long terme.

J'ai donc créé un outil simple pour faire exactement cela. La page de projet de virtualenv-mv le décrit un peu plus en détail, mais vous pouvez essentiellement l'utiliser virtualenv-mvcomme vous utiliseriez une implémentation simple de mv(sans aucune option).

Par exemple:

virtualenv-mv myproject project

Veuillez noter cependant que je viens de pirater cela. Il pourrait se briser dans des circonstances inhabituelles (par exemple, des virtualenvs liés par un lien symbolique) donc soyez prudent (sauvegardez ce que vous ne pouvez pas vous permettre de perdre) et faites-moi savoir si vous rencontrez des problèmes.

Six
la source