Rinominare una cartella virtualenv senza romperla


162

Ho creato una cartella e inizializzato un'istanza virtualenv in essa.

$ mkdir myproject
$ cd myproject
$ virtualenv env

Quando corro (env)$ pip freeze, mostra i pacchetti installati come dovrebbe.

Ora voglio cambiare titolo myproject/al project/.

$ mv myproject/ project/

Tuttavia, ora quando corro

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

dice che pip non è installato. Come rinominare la cartella del progetto senza rompere l'ambiente?


1
Questa domanda è vecchia e ha già una risposta, ma devo chiedermi, perché l'OP non potrebbe semplicemente riportare la virtualenv dov'era? Ovviamente ciò non risolve il desiderio di spostare / rinominare, ma ciò non ripristinerebbe un virtualenv funzionante o è già irrimediabilmente rotto?
Malik A. Rumi,

2
Sì, hai ragione, sarebbe riparare l'ambiente virtuale, ma non risolvere il problema.
Florian,

Novembre 2019, Python3. La migliore soluzione per me è descritta in aarongorka.com/blog/portable-virtualenv
Samir Sadek il

Risposte:


148

È necessario regolare l'installazione per utilizzare i percorsi relativi. virtualenvprevede questo con l' --relocatableopzione. Dai documenti :

Normalmente gli ambienti sono legati a un percorso specifico. Ciò significa che non è possibile spostare un ambiente o copiarlo su un altro computer. È possibile correggere un ambiente per renderlo riposizionabile con il comando:

$ virtualenv - ENV correlabile

NOTA: ENV è il nome dell'ambiente virtuale ed è necessario eseguirlo dall'esterno della directory ENV.

Ciò renderà alcuni dei file creati da setuptools o distribuirà l'utilizzo di percorsi relativi e cambierà tutti gli script per usare activ_this.py invece di usare la posizione dell'interprete Python per selezionare l'ambiente.

Nota: è necessario eseguirlo dopo aver installato i pacchetti nell'ambiente. Se si rende riposizionabile un ambiente, quindi installare un nuovo pacchetto, è necessario eseguire nuovamente virtualenv --relocatable.


2
avvertenza: la modifica di un env in trasferibile fa molto di più che consentire di spostare la cartella. (vedi la Nota: copiata dai documenti) ... potrebbe avere effetti collaterali.
Ben Roberts,

7
L'opzione --relocatable attualmente presenta una serie di problemi e non è garantito che funzioni in tutte le circostanze. È possibile che l'opzione venga deprecata in una versione futura di virtualenv. Inoltre, ciò non rende i pacchetti multipiattaforma. È possibile spostare la directory, ma può essere utilizzata solo su altri computer simili.
The Demz,

1
@TheDemz grep -EIr '\Wold_venv_name\W' /path/to/new_venvaiuterà a trovare eventuali shabang che usano la vecchia venv, ma non è una verifica completa della venv trasferita.
Piani cottura

2
Inoltre, dovrai modificare il .projectfile virtualenvwrapper , che contiene il percorso del codice sorgente che dipende da virtualenv, supponendo che tu stia utilizzando virutalenvwrapper e abbia anche rinominato la directory del progetto in modo che corrisponda al nuovo virtualenv.
Piani cottura

Ho dovuto disattivare virtualenv prima di eseguire questo.
antonagestam,

108

Credo che "sapere il perché" sia più importante del "sapere come" . Quindi, ecco un altro approccio per risolvere questo problema.

Quando esegui . env/bin/activate, esegue effettivamente i seguenti comandi (usando /tmpad esempio):

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

Tuttavia, avete appena rinominato myprojectper project, in modo che il comando non è stato eseguito. Questo è il motivo per cui dice pip is not installedche non è stato installato pipnell'ambiente globale del sistema e VirtualENV pipnon è stato fornito correttamente.

Se vuoi risolverlo manualmente, questo è il modo:

  1. Con il tuo editor preferito come Vim, modifica di /tmp/project/env/bin/activatesolito nella riga 42:

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

  2. Modifica /tmp/project/env/bin/pipnella riga 1:

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

Successivamente, riattiva il tuo ambiente virtuale enve vedrai che pipè tornato di nuovo.


6
Se si desidera modificare manualmente i percorsi, è necessario tenere presente che esistono più di due file codificati. Trova tutti con qualcosa come: grep -iHnR venv-name /path/to/venv-name | grep -v "^Binary file" | grep -i venv-name. In effetti, ho notato che in una delle mie istanze di Django, molti pacchetti contenevano il "percorso di Python sh-bang".
Kevin,

Questo mi ha aiutato molto. Avevo sicuramente bisogno di sapere perché ... Grazie!
Jarvis,

Contrariamente al commento di Keven di cui sopra, trovo che la modifica di queste due righe risolva tutti i problemi per quanto riguarda lo spostamento virtualenv. Forse c'è qualche caso d'uso che non sto usando e quindi non ho riscontrato il problema.
Deleet,

Grattalo! Oggi ho riscontrato un problema: ipython non funzionava all'interno di virtualenv. Per risolverlo, ho modificato l'intestazione bash (come si chiama?) Nel ipythonfile e poi ha funzionato bene.
Deleet,

Hmm, questo non funziona per me e sembra che il mio script di attivazione non abbia la riga 1 a cui si fa riferimento qui al passaggio 2. È cambiato qualcosa?
Evan Zamir,

40

NOTA: come @jb. sottolinea, questa soluzione si applica solo a messaggi facilmente (ri) creati virtualenv. Se un ambiente impiega diverse ore per installare questa soluzione non è consigliata


Virtualenvs sono fantastici perché sono facili da realizzare e cambiare; ti impediscono di rimanere bloccato in una singola configurazione. Se conosci i requisiti del progetto o puoi ottenerli, creane uno nuovovirtualenv :

  • Crea un requirements.txtfile

    (env)$ pip freeze > requirements.txt

    • Se non riesci a creare il requirements.txtfile, controlla env/lib/pythonX.X/site-packagesprima di rimuovere l'originale env.
  • Elimina quello esistente (env)

    deactivate && rm -rf env

  • Creane uno nuovo virtualenv, attivalo e installa i requisiti

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


In alternativa, usa virtualenvwrapper per rendere le cose un po 'più semplici poiché tutti i virtualenv sono conservati in una posizione centralizzata

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

6
Bene per alcune persone pip install -r requirements.txtrichiede un paio d'ore (compilando estensioni C di terze parti su Raspberry Pi).
jb.

4
Forse è vero, ma a me sembra un caso limite. Penso ancora che questa possa essere una soluzione praticabile per molti casi.
bnjmn,

Sì, molti progetti (ad esempio il sito Web di Django) impiegano solo 30 secondi per installare tutto, anche se hanno un paio di dozzine di dipendenze (a condizione che tu scarichi prima tutto e usi '--no-index --find-links = downloadDir' )
Jonathan Hartley l'

1
@bnjmn the one-liner virtualenv env && pip install -r requirements.txtNON installerà i requisiti nel nuovo ambiente perché non lo attivi
Yarin,

1
@Yarin Grazie per averlo sottolineato. Mi è totalmente mancato, essendo virtualenv-wrapperme stesso (che si attiva automaticamente alla creazione). Ho aggiornato la mia risposta per includere l'attivazione virtualenvnella speranza di evitare qualsiasi confusione.
bnjmn,

28

Installo sempre virtualenvwrapper per dare una mano. Dal prompt della shell:

pip install virtualenvwrapper

C'è un modo documentato nei documenti virtualenvwrapper - cpvirtualenv Questo è quello che fai. Assicurati di essere fuori dal tuo ambiente e tornare al prompt della shell. Digita questo con i nomi richiesti:

cpvirtualenv oldenv newenv

E poi, se necessario:

rmvirtualenv oldenv

Per andare al tuo nuovo utente:

workon newenv

1
La risposta di Af Microwave dovrebbe essere davvero il metodo accettato.
Jaxian,

Funziona solo se si sta usando virtualenvwrapper, non solo virtualenv. Questa risposta di @ryankdwyer è migliore.
LS

Ho modificato la mia risposta per riflettere che si dovrebbe installare 'virtualenvwrapper'. Supponendo che la ridenominazione degli ambienti virtuali avvenga molto, lo consiglierei in questo modo.
Forno a microonde,

Anche se si basa su virtualenvwrapper, è il più semplice. E funziona bene.
Blasrodri,

17

È possibile risolvere il problema seguendo questi passaggi:

  1. rinomina la tua directory
  2. riesegui questo: $ virtualenv ..\path\renamed_directory
  3. virtualenv correggerà le associazioni di directory lasciando i pacchetti al loro posto
  4. $ scripts/activate
  5. $ pip freeze per verificare che i tuoi pacchi siano a posto
  6. Un avvertimento importante, se si hanno dipendenze di percorsi statici nei file di script nella directory virtualenv, è necessario modificarli manualmente.

1
Questa è stata un'ottima soluzione per me. Poiché questa soluzione può evitare alcuni dei problemi associati --relocatable, penso che questa soluzione sia migliore della risposta accettata. Finora, ho notato che molti .pycfile _new_name_/lib/python2.7fanno ancora riferimento _old_name_. Tuttavia, ciò non sembra influire sul funzionamento del mio ambiente. Forse l'unica soluzione migliore sta usando virtualenvwrappero alcune delle altre utilità menzionate tra le risposte qui. Almeno questa soluzione non richiede l'installazione di programmi aggiuntivi.
LS

Funziona come un fascino!
AmirHossein,

13

Un altro modo per farlo che ha funzionato per me molte volte senza problemi è virtualenv-clone :

pip install virtualenv-clone
virtualenv-clone old-dir/env new-dir/env

Questo dovrebbe essere contrassegnato come la migliore risposta. Mani giù! Ci è voluto del tempo per clonare, quindi abbiate pazienza ragazzi.
Amitrajit Bose,

virtualenv-clone trascura di aggiornare il prompt. Ho dovuto farlo manualmente. A parte questo, è fantastico.
user3667349

5

(all'interno della cartella del progetto)

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

Non dimenticare di disattivare e attivare


Funziona bene; O per il percorso Linux:sed -i "s|$old_dir|$new_dir|g" bin/*
Destroyica,

sed -i '.original' 's/old_dir_name/new_dir_name/g' *per mac
Alex,

1

virtualenv --relocatable ENVnon è una soluzione desiderabile. Presumo che la maggior parte delle persone voglia la possibilità di rinominare un virtualenv senza effetti collaterali a lungo termine.

Quindi ho creato un semplice strumento per fare proprio questo. La pagina del progetto per virtualenv-mv lo delinea in modo un po 'più dettagliato, ma essenzialmente puoi usarlo virtualenv-mvproprio come faresti con una semplice implementazione di mv(senza alcuna opzione).

Per esempio:

virtualenv-mv myproject project

Si noti tuttavia che ho appena hackerato questo. Potrebbe rompersi in circostanze insolite (ad esempio virtualenvs con link simbolici), quindi fai attenzione (esegui il backup di ciò che non puoi permetterti di perdere) e fammi sapere se riscontri problemi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.