Umbenennen eines virtualenv-Ordners, ohne ihn zu beschädigen

162

Ich habe einen Ordner erstellt und eine virtualenv-Instanz darin initialisiert.

$ mkdir myproject
$ cd myproject
$ virtualenv env

Wenn ich starte (env)$ pip freeze, werden die installierten Pakete so angezeigt, wie sie sollten.

Jetzt möchte ich umbenennen myproject/in project/.

$ mv myproject/ project/

Jetzt aber, wenn ich renne

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

es heißt, pip ist nicht installiert. Wie benenne ich den Projektordner um, ohne die Umgebung zu beschädigen?

Riley Watkins
quelle
1
Diese Frage ist alt und hat bereits eine Antwort, aber ich muss mich fragen, warum das OP die virtuelle Umgebung nicht einfach dorthin zurückversetzen konnte, wo sie war. Das löst natürlich nicht den Wunsch nach Verschieben / Umbenennen, aber würde das nicht eine funktionierende virtuelle Umgebung wiederherstellen, oder ist sie bereits hoffnungslos kaputt?
Malik A. Rumi
2
Ja, Sie haben Recht, es würde die virtuelle Umgebung reparieren, aber das Problem nicht lösen.
Florian
November 2019, Python3. Die beste Lösung für mich ist in aarongorka.com/blog/portable-virtualenv
Samir Sadek

Antworten:

148

Sie müssen Ihre Installation anpassen, um relative Pfade zu verwenden. virtualenvsieht dies mit der --relocatableOption vor. Aus den Dokumenten :

Normalerweise sind Umgebungen an einen bestimmten Pfad gebunden. Das bedeutet, dass Sie eine Umgebung nicht verschieben oder auf einen anderen Computer kopieren können. Sie können eine Umgebung so einrichten, dass sie mit dem folgenden Befehl verschoben werden kann:

$ virtualenv - relocatable ENV

HINWEIS: ENV ist der Name der virtuellen Umgebung und muss von außerhalb des ENV-Verzeichnisses ausgeführt werden.

Dadurch werden einige der von setuptools oder Distribute erstellten Dateien relative Pfade verwenden und alle Skripte so ändern, dass activ_this.py verwendet wird, anstatt den Speicherort des Python-Interpreters zur Auswahl der Umgebung zu verwenden.

Hinweis: Sie müssen dies ausführen, nachdem Sie Pakete in der Umgebung installiert haben. Wenn Sie eine Umgebung verschiebbar machen und dann ein neues Paket installieren, müssen Sie virtualenv --relocatable erneut ausführen.

ire_and_curses
quelle
2
Einschränkung: Wenn Sie eine Umgebung in eine verschiebbare Umgebung ändern, können Sie nicht nur den Ordner verschieben. (siehe Hinweis: aus den Dokumenten kopiert) ... es kann Nebenwirkungen haben.
Ben Roberts
7
Die Option --relocatable weist derzeit eine Reihe von Problemen auf und funktioniert nicht unter allen Umständen. Es ist möglich, dass die Option in einer zukünftigen Version von virtualenv veraltet ist. Dies macht Ihre Pakete auch nicht plattformübergreifend. Sie können das Verzeichnis verschieben, es kann jedoch nur auf anderen ähnlichen Computern verwendet werden.
Der Demz
1
@TheDemz grep -EIr '\Wold_venv_name\W' /path/to/new_venvhilft bei der Suche nach Shabangs, die das alte Venv verwenden, ist jedoch keine vollständige Überprüfung des verlagerten Venv.
Kochfelder
2
Außerdem müssen Sie die .projectDatei virtualenvwrapper bearbeiten , die den Pfad zum Quellcode enthält, der von virtualenv abhängt, vorausgesetzt, Sie verwenden virutalenvwrapper und haben das Projektverzeichnis entsprechend der neuen virtualenv umbenannt.
Kochfelder
Ich musste die virtuelle Umgebung deaktivieren, bevor ich sie ausführen konnte.
Antonagestam
108

Ich glaube, "zu wissen warum" ist wichtiger als "zu wissen wie" . Hier ist ein anderer Ansatz, um dies zu beheben.

Wenn Sie ausführen . env/bin/activate, werden tatsächlich die folgenden Befehle ausgeführt ( /tmpz. B.):

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

Sie haben jedoch nur umbenannt myprojectzu project, so dass der Befehl ausführen fehlgeschlagen. Aus diesem Grund heißt es pip is not installed, dass Sie nicht pipin der globalen Systemumgebung installiert haben und Ihre virtuelle Umgebung pipnicht korrekt bezogen ist.

Wenn Sie dies manuell beheben möchten, gehen Sie wie folgt vor:

  1. Ändern Sie mit Ihrem Lieblingseditor wie Vim /tmp/project/env/bin/activatenormalerweise in Zeile 42:

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

  2. Ändern Sie /tmp/project/env/bin/pipin Zeile 1:

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

Aktivieren Sie danach Ihre virtuelle Umgebung enverneut und Sie werden sehen, dass Ihre pipwieder zurückgekehrt ist.

Heilige
quelle
6
Wenn das manuelle Ändern der Pfade gewünscht wird, sollte beachtet werden, dass mehr als zwei fest codierte Dateien vorhanden sind. Finden Sie sie alle mit etwas wie : grep -iHnR venv-name /path/to/venv-name | grep -v "^Binary file" | grep -i venv-name. Tatsächlich bemerkte ich, dass in einer meiner Django-Instanzen viele Pakete den "Pfad zu Python sh-bang" enthielten.
Kevin
Das hat mir sehr geholfen. Ich musste unbedingt wissen warum ... Danke!
Jarvis
Im Gegensatz zu Kevens obigem Kommentar finde ich, dass das Bearbeiten dieser beiden Zeilen alle Probleme in Bezug auf das Verschieben für mich löst virtualenv. Vielleicht gibt es einen Anwendungsfall, den ich nicht verwende und daher nicht auf das Problem stoße.
Deleet
Vergiss das! Heute bin ich auf ein Problem gestoßen: ipython würde innerhalb der nicht funktionieren virtualenv. Um es zu lösen, habe ich den Bash-Header (wie heißt er?) In der ipythonDatei bearbeitet und dann hat es gut funktioniert.
Deleet
Hmm, das funktioniert bei mir nicht und es scheint, dass mein Aktivierungsskript nicht die Zeile 1 enthält, auf die hier in Schritt 2 Bezug genommen wird. Hat sich etwas geändert?
Evan Zamir
40

HINWEIS: Als @jb. weist darauf hin, dass diese Lösung nur für einfach (neu) erstellte virtualenvs gilt. Wenn die Installation einer Umgebung mehrere Stunden dauert, wird diese Lösung nicht empfohlen


Virtualenvs sind großartig, weil sie einfach zu erstellen und umzuschalten sind. Sie verhindern, dass Sie an eine einzelne Konfiguration gebunden werden. Wenn Sie die Projektanforderungen kennen oder erhalten können, erstellen Sie eine neuevirtualenv :

  • Erstellen Sie eine requirements.txtDatei

    (env)$ pip freeze > requirements.txt

    • Wenn Sie die requirements.txtDatei nicht erstellen können , überprüfen Sie dies, env/lib/pythonX.X/site-packagesbevor Sie das Original entfernen env.
  • Löschen Sie die vorhandene (env)

    deactivate && rm -rf env

  • Erstellen Sie eine neue virtualenv, aktivieren Sie sie und installieren Sie die Anforderungen

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


Alternativ können Sie virtualenvwrapper verwenden, um die Arbeit etwas zu vereinfachen, da alle virtualenvs an einem zentralen Ort aufbewahrt werden

$(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
quelle
6
Nun, für einige Leute pip install -r requirements.txtdauert es ein paar Stunden (Kompilieren von C-Erweiterungen von Drittanbietern auf Himbeer-Pi).
jb.
4
Vielleicht stimmt das, aber das scheint mir ein Randfall zu sein. Ich denke immer noch, dass dies in vielen Fällen eine praktikable Lösung sein kann.
Bnjmn
Ja, viele Projekte (z. B. die Django-Website) benötigen nur 30 Sekunden, um alles zu installieren, selbst wenn sie ein paar Dutzend Abhängigkeiten aufweisen (vorausgesetzt, Sie laden zuerst alles herunter und verwenden '--no-index --find-links = downloadDir'). )
Jonathan Hartley
1
@bnjmn der Einzeiler virtualenv env && pip install -r requirements.txtwird die Anforderungen NICHT in der neuen Umgebung installieren, weil Sie es nicht aktivieren
Yarin
1
@ Yarin Danke, dass du darauf hingewiesen hast. Ich habe es total vermisst, virtualenv-wrapperBenutzer selbst zu sein (was bei der Erstellung automatisch aktiviert wird). Ich habe meine Antwort aktualisiert, um die Aktivierung zu aktivieren, virtualenvum Verwirrung zu vermeiden.
Bnjmn
28

Ich installiere immer virtualenvwrapper, um zu helfen. Von der Shell-Eingabeaufforderung:

pip install virtualenvwrapper

In den virtualenvwrapper-Dokumenten ist eine Möglichkeit dokumentiert: cpvirtualenv Dies ist, was Sie tun. Stellen Sie sicher, dass Sie sich nicht in Ihrer Umgebung befinden und zur Shell-Eingabeaufforderung zurückkehren. Geben Sie dies mit den erforderlichen Namen ein:

cpvirtualenv oldenv newenv

Und dann, wenn nötig:

rmvirtualenv oldenv

So gehen Sie zu Ihrem neuen:

workon newenv
Afrowave
quelle
1
Die Antwort von Afrowave sollte wirklich die akzeptierte Methode sein.
Jaxian
Dies funktioniert nur, wenn man verwendet virtualenvwrapper, nicht nur virtualenv. Diese Antwort von @ryankdwyer ist besser.
LS
Ich habe meine Antwort so bearbeitet, dass man 'virtualenvwrapper' installieren sollte. Unter der Annahme, dass das Umbenennen virtueller Umgebungen häufig vorkommt, würde ich diesen Weg empfehlen.
Afrowave
Obwohl es auf virtualenvwrapper basiert, ist es das einfachste. Und es funktioniert gut.
Blasrodri
17

Sie können Ihr Problem folgendermaßen beheben:

  1. Benennen Sie Ihr Verzeichnis um
  2. Führen Sie dies erneut aus: $ virtualenv ..\path\renamed_directory
  3. virtualenv korrigiert die Verzeichniszuordnungen, während Ihre Pakete an Ort und Stelle bleiben
  4. $ scripts/activate
  5. $ pip freeze um zu überprüfen, ob Ihre Pakete vorhanden sind
  6. Eine wichtige Einschränkung: Wenn Sie statische Pfadabhängigkeiten in Skriptdateien in Ihrem virtualenv-Verzeichnis haben, müssen Sie diese manuell ändern.
Ryankdwyer
quelle
1
Dies war eine sehr gute Lösung für mich. Da diese Lösung einige der damit verbundenen Probleme vermeiden kann--relocatable , denke ich, dass diese Lösung besser ist als die akzeptierte Antwort. Bisher ist mir aufgefallen, dass sich viele .pycDateien _new_name_/lib/python2.7noch auf beziehen _old_name_. Dies scheint jedoch keinen Einfluss auf die Funktionsweise meiner Umgebung zu haben. Vielleicht ist die einzig bessere Lösung die Verwendung virtualenvwrapperoder einiger der anderen Dienstprogramme, die in den Antworten hier erwähnt werden. Zumindest erfordert diese Lösung keine Installation zusätzlicher Programme.
LS
Klappt wunderbar!
AmirHossein
13

Ein weiterer Weg, der für mich viele Male ohne Probleme funktioniert hat, ist virtualenv-clone :

pip install virtualenv-clone
virtualenv-clone old-dir/env new-dir/env
Antony Hatchkins
quelle
Dies sollte als die beste Antwort markiert werden. Hände runter! Das Klonen hat einige Zeit gedauert, also hab Geduld, Leute.
Amitrajit Bose
virtualenv-clone vernachlässigt es, die Eingabeaufforderung zu aktualisieren. Musste das manuell machen. Davon abgesehen ist es großartig.
user3667349
5

(im Projektordner)

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

Vergessen Sie nicht, zu deaktivieren und zu aktivieren

Ignacio
quelle
Funktioniert gut; Oder für Linux-Pfad:sed -i "s|$old_dir|$new_dir|g" bin/*
Destroyica
sed -i '.original' 's/old_dir_name/new_dir_name/g' *für Macs
Alex
1

virtualenv --relocatable ENVist keine wünschenswerte Lösung. Ich gehe davon aus, dass die meisten Leute die Möglichkeit haben möchten, eine virtuelle Umgebung ohne langfristige Nebenwirkungen umzubenennen .

Deshalb habe ich ein einfaches Tool erstellt, um genau das zu tun. Die Projektseite für virtualenv-mv beschreibt es etwas detaillierter, aber im Wesentlichen können virtualenv-mvSie es genauso verwenden, wie Sie eine einfache Implementierung von mv(ohne Optionen) verwenden würden.

Beispielsweise:

virtualenv-mv myproject project

Bitte beachten Sie jedoch, dass ich dies gerade gehackt habe. Es kann unter ungewöhnlichen Umständen (z. B. mit verknüpften virtuellen Umgebungen) kaputt gehen. Seien Sie also vorsichtig (sichern Sie, was Sie sich nicht leisten können, zu verlieren) und lassen Sie mich wissen, wenn Sie auf Probleme stoßen.

Sechs
quelle