Puis-je déplacer un virtualenv?

89

Cette question n'est pas un doublon.

Il ne s'agit pas seulement de renommer un environnement virtuel, mais aussi de le déplacer vers un répertoire différent, y compris, potentiellement, le répertoire d'un autre utilisateur.

Ce n'est pas la même chose que de simplement renommer un environnement virtuel, en particulier pour les personnes qui ne connaissent pas les virtualenvs.

Si je crée un virtualenv et que je le déplace vers un autre dossier, cela fonctionnera-t-il toujours?

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

... plus tard dans la journée, l'environnement virtuel A DÉPLACÉ ...

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

Question:

Est-ce que ça va marcher?

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

Je veux dire cela comme moins une question sur la sagesse d'essayer ceci (à moins que cette sagesse soit humoristique, bien sûr), et plus sur la question de savoir si c'est possible. Je veux vraiment savoir s'il est possible de le faire en Python 3, ou si je dois juste l' aspirer et le cloner.

Puis-je juste mvun virtualenvcomme ça sans tristesse? Je veux éviter la tristesse.

Nathan Basanese
la source

Réponses:

69

Oui. Il est possible de le déplacer sur la même plateforme. Vous pouvez utiliser --relocatablesur un environnement existant.

De --help:

--relocatable - Rend un environnement virtualenv EXISTANT déplaçable. Cela corrige les scripts et rend tous les fichiers .pth relatifs.

CEPENDANT, cela ne semble PAS changer le activatescript, mais ne change que les scripts pip*et easy_install*. Dans le activatescript, la $VIRTUAL_ENVvariable d'environnement codée en dur comme l'original /path/to/original/venv. La $VIRTUAL_ENVvariable est également utilisée pour définir le PATHde votre environnement actif, elle doit donc être modifiée en fonction du nouvel emplacement afin d'appeler pythonet pipetc. sans chemin absolu.

Pour résoudre ce problème, vous pouvez modifier la $VIRTUAL_ENVvariable d'environnement dans le activatescript (par exemple en utilisantsed ), et tout devrait être prêt.

Un exemple d'utilisation:

$ 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

Hourra, maintenant vous pouvez installer des choses et les charger dans votre nouvel environnement virtuel.

hilcharge
la source
//, Hm. Cela ne semble pas finir par les rendre déplaçables. Je reçois toujours des erreurs sur le fait qu'ils ne sont pas des fichiers de script "normaux".
Nathan Basanese
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. " (C'est moi qui souligne) voir le guide de
BobTuckerman
1
J'ai essayé cela sur Windows et l'erreur répertorie tous les scripts (* .py, * .bat, * .ps1) dans le Scriptsrépertoire (équivalent à binon * nix) et dit quelque chose comme activate.ps1 cannot be made relative (it's not a normal script that starts with #!c:\..python.exe.fondamentalement, il se plaint que le hachage dans le fichier l'en-tête n'est pas le python.exe de virtualenv actuel, c'est celui que j'ai déplacé de -easy fixed. J'ai regardé dans ce script chic et il découvre déjà son propre chemin de toute façon - sympa. Certains des autres scripts ne reposent pas non plus sur des chemins (par exemple, deactivate.bat), donc en bref, cela fonctionne.
Davos
2
@NathanBasanese le message activate.ps1 cannot be made relativepeut être ignoré car ce script est déjà relatif. Le message n'est pas utile sous Windows, car les scripts n'utilisent pas de #!directives comme sous Linux pour indiquer au shell quelle application doit l'exécuter. Le activate.batn'est pas modifié, mais il n'est pas utilisé (au moins sur Windows 10, l'appel activatelance le script PoSH) donc non, je n'ai pas eu besoin de modifier les scripts. Le problème est de savoir pip.exequi a un chemin vers python codé en dur et doit être modifié avec un éditeur hexadécimal, ou simplement une réinstallation.
Davos
3
@Sgedda Rétrospectivement, je dirais de ne pas faire ça. Vos environnements python doivent être facilement recréables en utilisant au minimum pip freezeun fichier d'exigences afin que vous puissiez facilement réinstaller tous vos packages, docker (fonctionne bien avec virtualenv installé dessus), conda, pyenv ou d'autres outils. Vous devriez pouvoir créer et détruire des environnements en tant qu'infrastructure immuable, ils ne devraient pas être précieux.
Davos
15

Pour Python 3.3+ (avec un nouveau venvmodule intégré)

Réponse courte (quelle que soit la version):

  • Il n'y a pas de moyen propre et direct de déplacer un environnement virtuel
  • Recréez simplement, c'est facile !!


Longue réponse:

Depuis Python v3.3, virtualenvest devenu un module intégré nommé venv.

L' --relocatableoption mentionnée dans d'autres réponses n'a pas été incluse dans venv, et actuellement, il n'y a pas de moyen sûr et sûr à ma connaissance de renommer ou de déplacer un environnement virtuel Python.

Cependant, il existe un moyen assez simple de recréer simplement un environnement virtuel, avec tous ses packages actuellement installés. Consultez cette réponse ou consultez la section ci-dessous pour obtenir des informations sur la recréation d'un environnement virtuel. Au cours du processus, vous pouvez recréer le nouvel environnement dans n'importe quel endroit et avec le nom de votre choix. Ou consultez la section ci-dessous pour le processus.

Dans cette réponse, il mentionne quelques autres packages tiers qui peuvent prendre en charge les changements de noms ou les déplacements directs. Si vous êtes décidé à rechercher un moyen de déplacer un environnement virtuel intact, vous pouvez vérifier si ceux-ci fonctionnent venvégalement.

Remarque: Dans cette réponse, il est axé sur virtualenv, plutôt que sur venv. Voir ci-dessous pour savoir comment traduire.



venvvs virtualenvsyntaxe de commande plus ancienne

La commande à utiliser venvest:

python -m venv

plutôt que simplement virtualenv, qui s'installe en tant que commande dans le package d'origine. Où «python» fait référence à la façon dont vous exécutez votre exécutable python, ce qui peut être une variété de choses, telles que:

  1. python
  2. pyou py -3.7ou similaire (le lanceur Python pour Windows pour Python 3.3+ et Windows uniquement pour le moment)
  3. python3 (convention pour les environnements Linux qui installent en double python 2 et 3)
  4. Si vous rencontrez des problèmes, utilisez le chemin absolu de l'exécutable python que vous souhaitez exécuter: par exemple c:\program files\python37\python.exe

Si vous ne savez pas quelle version est exécutée, vous pouvez toujours python --versionle savoir.



Comment recréer un environnement virtuel

Créer / recréer un environnement virtuel est facile et devrait devenir une seconde nature après avoir travaillé un peu avec eux. Ce processus reflète ce que vous feriez pour distribuer votre script en tant que package (avec ses dépendances) dans la première moitié, puis ce que quelqu'un ferait pour installer votre script / package pour un développement ultérieur.

Tout d'abord, obtenez une liste mise à jour de ce qui se trouve dans l'environnement virtuel. Lorsqu'il est actif, obtenez la version de Python qu'il utilise et enregistrez la liste des dépendances dans un fichier.

  1. Utiliser python --versionavec l'environnement virtuel activé pour voir quelle version de Python il utilise.

    • C'est pour plus de clarté - vous pouvez mettre à jour la version Python pour diverses raisons - au moins vers la dernière version du correctif
    • Par exemple, si le venv existant utilise Python v3.7.4, mais que maintenant la v3.7.6 est hors service, utilisez la v3.7.6 à la place, qui ne devrait inclure que des correctifs de sécurité et de bogues sans rupture.
  2. Utilisez python -m pip freeze > requirements.txtpour créer la liste des dépendances actuelles du package et les mettre dans lerequirements.txt fichier. Cette commande fonctionne sous Linux ou Git Bash à coup sûr - pas sûr à 100% de Powershell ou de la ligne de commande sous Windows.

Créez maintenant un nouvel environnement virtuel, puis ajoutez les dépendances de l'ancien.

  1. Faites votre nouveau venv.

    • Assurez-vous que vous utilisez la bonne version de python que vous souhaitez installer sur le venv.
    • Si vous voulez que ce soit exactement la même version de Python:
      • Exécutez python directement à partir de l'environnement virtuel actuel (avec celui-ci activé), et utilisez simplement pythoncomme commande
      • Ou utilisez un chemin absolu avec python.exedans le dossier de l'environnement virtuel
    • Pour la nouvelle entrée de dossier venv dans la commande:
      • Ajoutez un chemin absolu ou relatif à l'emplacement de dossier final souhaité.
      • Permet python -m venv my_new_venvde créer un nouvel environnement virtuel dans le répertoire de travail actuel dans un nouveau my_new_venvdossier.
      • Le nom du dossier venv sera le nom du venv (ce qui apparaît dans l'invite lorsqu'il est activé).
  2. Installez vos dépendances à partir du requirements.txtfichier.

    • python -m pip install -r requirements.txt

Vous devrez peut-être réinstaller les packages locaux qui sont en mode de développement.

Notez que si vous avez besoin de voir l'emplacement spécifique dans lequel un package est installé, utilisez:

  • python -m pip list -v
  • L' -voption ou "verbose" ajoutera des informations supplémentaires sur chaque paquet qui est installé, y compris le chemin dans lequel il est installé. Ceci est utile pour vous assurer que vous gardez les paquets virtuels, utilisateur et système installés.

À ce stade, vous pouvez simplement supprimer l'ancien dossier venv et tout son contenu. Je recommande d'utiliser une interface graphique pour cela - les suppressions de fichiers sont souvent permanentes à partir de la ligne de commande Linux, et une petite faute de frappe peut être une mauvaise nouvelle.

LightCC
la source
N'y a-t-il aucun moyen de copier l'état de venv pip, c'est-à-dire sans avoir à retélécharger toutes les bibliothèques avec pip?
Aydo
Je ne suis pas sûr de la raison pour laquelle vous le souhaiteriez - est-ce dû à une situation de bande passante extrêmement faible vers Internet ou à un besoin massif de dupliquer beaucoup? Je pense que vous pouvez obtenir tous les zips de pypi et ensuite les installer localement, mais je ne suis pas au courant de cela. Je sais que vous pouvez configurer un serveur pip local pour héberger des packages.
LightCC
Le problème (que j'essaie de résoudre) est que je souhaite exécuter un script python sur une machine qui ne permet pas au trafic réseau de passer (ou presque n'importe où). Je peux mettre des fichiers dessus, mais il ne peut pas parler à pip. Un cas de niche bien sûr, mais c'est exactement pourquoi je dois déplacer ces choses.
Richard Rast
@RichardRast C'est un problème différent, je réponds juste à la question initiale. Remarque: il existe des solutions à votre problème (téléchargez les packages sous forme de zips et installez localement, exécutez un serveur miroir PyPi derrière votre pare-feu, etc.), mais ce n'est pas la bonne: Q&R pour cela ..
LightCC
2
Vous pouvez créer des roues à partir de tous vos packages avec pip wheel . -w wheels, puis réinstaller simplement les packages dans le nouvel environnement virtuel avecpip install --no-index --find-links /path/to/wheels/ -r requirements.txt
np8
7

L' --relocatableargument à virtualenvsemble vous permettre de faire cela.

Ruth Franklin
la source
//, Cela repose-t-il simplement sur des chemins relatifs, ou est-ce que cela se dérobe d'une manière ou d'une autre?
Nathan Basanese
1
--relocatable ne fonctionne que dans les environnements virtuels existants. Exécutez virtualenv --relocatable my-python-venvAPRÈS que l'environnement existe déjà.
hilcharge le
1
De --help: This fixes up scripts and makes all .pth files relative. Non, cela ne fera pas de bibliothèques indépendantes de la plate-forme. Si vous souhaitez le déplacer sur une plate-forme différente, vous devez le réinstaller en fonction du python local.
hilcharge le
5
le module venv python3 ne prend pas en charge ce drapeau
Nelson
7

MAIS HÉLAS:

Non, vous ne pouvez pas simplement mv. Il existe des solutions de contournement, mais il peut être plus facile de réinstaller.

(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
$ 

... presse enterbeaucoup dans la frustration, et les travaux suivants

$
$
$ pip3 search foaas

Sauf que ce n'est pas de la my-python-venvtristesse.

Vous voulez mvvotre virtualenvet l'utiliser, sinon non modifié?

Réponse courte:

Je vais laisser Boromir le dire, afin qu'il puisse le préciser:

Eh bien, tu ne peux pas .

Nathan Basanese
la source
2
à moins que vous ne vouliez devenir sanglant et le modifier de manière appropriée: ce sont les liens dans les binaires de la corbeille qui causent le problème de mouvement. Si vous savez d'où vous venez, vous pouvez utiliser quelque chose comme find bin -type f -exec ex -sc "%s,${FROM},${PWD},g|x" {} \;supposer que votre bin et votre lib sont dans votre dossier venv actuel. J'utilise cela comme un moyen rapide et sale de copier et de déplacer des environnements virtuels python3 avec de nombreux packages pip installés.
Paul Whipp
1
@PaulWhipp Y a-t-il un avantage à utiliser cette commande par rapport à simplement utiliser --relocatable? Aussi, Nathan, excellente question mais c'est une réponse terrible. Accepter sa propre réponse est toujours un peu biaisé, sauf si elle est bien écrite et énumère clairement les options, mais déterminer que vous-même serait de toute façon subjectif.
Davos
1
@Davos --relocatable n'a pas fonctionné pour moi mais je déplace régulièrement les venvs python3 en piratant les binaires et jusqu'à présent je n'ai eu aucun problème.
Paul Whipp
1
J'avais laissé entendre que vous devriez changer accepté pour une réponse différente (c'est-à-dire pas la vôtre) Peut-être celle choisie par le peuple: D
Davos
3
La question était "puis-je simplement mvun venv?", Et la réponse est "non, vous ne pouvez pas simplement mv, il existe des solutions de contournement mais il pourrait être plus facile de réinstaller". Si c'était la meilleure réponse, cela ferait gagner du temps à moi et à d'autres.
Nickolay
5

Oui, cela devrait être possible si vous n'avez rien fait qui dépend du répertoire actuel du virtualenv.

Cependant, si vous avez le choix, la meilleure chose à faire est de créer un nouveau virtualenv et de commencer à utiliser le nouveau virtualenv à la place. C'est le choix le plus sûr et le moins susceptible de causer des problèmes plus tard.

La documentation mentionne que :

Chaque virtualenv contient des informations de chemin codées en dur,

Par exemple, si vous avez exécuté setvirtualenvproject il ne sera pas en mesure de basculer vers le bon répertoire une fois que vous avez exécuté workon ..., vous devrez donc résoudre ce problème manuellement.

En général, virtualenv n'est guère plus qu'un répertoire avec les fichiers d'interprétation Python nécessaires ainsi que les packages dont vous avez besoin.

Siméon Visser
la source
2

En utilisant les réponses à ce sujet et à d'autres sujets sur un sujet similaire, j'ai créé un script bash qui, localisé et exécuté dans le répertoire virtualenv lui - même , vous aidera avec vos déplacements virtualenv.

Après cela, virtualenv --relocatable yourenvvous devrez changer votre VIRTUAL_ENVvariable chaque fois que vous déplacez le répertoire, donc si vous ne voulez pas le changer manuellement, utilisez ceci.

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

J'espère que cela aide.

Gerbes
la source
0

OUI, VOUS POUVEZ! (Danswindows )

La solution de contournement est simple, déplacez simplement votre environnement virtuel n'importe où, puis modifiez-le à l' activate.batintérieur scripts\:

  1. Déplacer vers l'environnement virtuel vers le répertoire souhaité

  2. Cliquez avec le bouton droit de la souris et modifiez activate.batsitué à venv_folder\scripts.

  3. Changer la VIRTUAL_ENVvariable de:

     set VIRTUAL_ENV=C:\old_directory\venv_name
    

    dans

     set VIRTUAL_ENV=C:\new_directory\venv_name
    
  4. Enregistrez le fichier de commandes édité, et c'est tout!

REMARQUE: ma solution devrait fonctionner et enregistrer la windows usersconfiguration de nouveaux environnements virtuels, je doute que cela fonctionnera dans un autre système d'exploitation car il .batprovient deMS-DOS

Kyle Olodin
la source
Changer old_directorypour old_directory- est-ce une faute de frappe?
acquitter
aww putain, oui c'est merci
kyle olodin