2015-05-18 17 views
12

Sto usando virtualenv per cambiare il mio python dev env. Ma quando ho eseguito workon my_env, mi capita di incontrare tale messaggio di errore:disattiva conflitto in virtualenvwapper e anaconda

Error: deactivate must be sourced. Run 'source deactivate' 
instead of 'deactivate'. 

Usage: source deactivate 

removes the 'bin' directory of the environment activated with 'source 
activate' from PATH. 

Dopo alcune ricerche su Google, sembra che workon, che è definito nella /usr/local/bin/virtualenvwrapper.sh, chiamate deactivate. E c'è una sceneggiatura con lo stesso nome presente nel cestino di Anaconda, quindi viene chiamata per errore da workon.

Qualche suggerimento per aggirare questo conflitto?

risposta

3

È possibile modificare /usr/local/bin/virtualenvwrapper.sh per rendere deactivate punto su un percorso assoluto a qualsiasi deactivate si suppone che faccia riferimento.

+2

Dove viene disattivato il diritto? Ho usato brew per installare il mio virtualenvwrapper. E ci sono così tanti "disattivati" in /usr/local/bin/virtualenvwrapper.sh. Qualche soluzione elegante per cambiare la disattivazione che usa? – Scofield77

+0

virtualenvwrapper si aspetta che la disattivazione sia una funzione di shell, non esiste alcun percorso a cui puntare. – quodlibetor

15

Una soluzione che funziona per me è rinominare deactivate nel bidone di Anaconda:

mv deactivate conda-deactivate

+0

Ho scelto lo stesso nome prima di vedere questa risposta. +1 per 'conda-deactivate' come nuovo standard! – vabada

+3

Questo è fragile poiché anche il conda viene disattivato in più punti. – FredrikHedman

1

in Anaconda activate è uno script eseguibile si trova nella directory Anaconda bin, ma è una funzione in in virtualenvwrapper.sh. Quindi questo è un problema di collisione nello spazio dei nomi, ma anche un caso di sovrapposizione di funzionalità.

Anacondas è una distribuzione python e, tra le altre cose, supporta l'ambiente virtuale tramite conda env mentre virtualenvwrapper è focalizzato sul funzionamento con diversi ambienti virtuali. La sola rinomina dello script anaconda/bin/activate è una soluzione fragile e potrebbe rompersi conda.

Il codice di virtualenvwrapper.sh (funzione workon) esegue deactivate che si verifica utilizzando lo script anaconda. Questo script restituisce un errore. Il codice workon continua e rimuove il nome deactivate e genera il proprio deactivate e crea anche una funzione deactivate al volo.

In sintesi, fa la cosa giusta e l'errore può essere visualizzato più come un avviso. Se si vuole farlo andare via è possibile modificare la funzione workon (cercare la linea # Deactivate any current environment "destructively")

deactivate 
--> 
deactivate >/dev/null 2>&1 

(Ho suggerito questo cambiamento al maintainer virtualenvwrapper)

9

Sono d'accordo con il commento di @ FredrikHedman che rinominare gli script nella directory anaconda/miniconda bin ha il potenziale per essere fragile. Il suo post completo mi ha portato a quella che sento sia una risposta più solida. (Grazie!)

Piuttosto che semplicemente buttare via eventuali errori generati chiamando deactivate, potremmo semplicemente condizione che chiamata se la funzionesarebbe chiamato contro il file di. Come accennato, virtualenv e virtualenvwrapper creano una funzione denominata deactivate; i * condas chiamano un file di script con lo stesso nome.

Così, nello script virtualenvwrapper.sh, siamo in grado di modificare le seguenti due linee che prova per se deactivate è soltanto callable:

type deactivate >/dev/null 2>&1 
if [ $? -eq 0 ] 

con il test più severo per se si tratta di una funzione di shell:

nametype="$(type -t deactivate)" 
if [ "${nametype##* }" == "function" ] 

Questa modifica evita di attivare l'errore spurio annotato nella domanda originale, ma non rischia di reindirizzare altri errori utili o di produrre nell'oblio silenzioso.

Si noti la sostituzione variabile su nametype nel confronto. Questo perché l'output di type -f in zsh restituisce qualcosa come "name: type" anziché bash che restituisce semplicemente "type". La sostituzione cancella tutto fino all'ultimo carattere dello spazio, se esistono spazi, lasciando solo il valore del tipo. Questo inoffensivo non fa nulla in bash. (Sarei entusiasta di ottenere suggerimenti sulla codifica cross-shell su questo.)

Come sempre, apprezzo feedback costruttivo e commenti!

+0

Grazie per questa soluzione perfetta. – miku

+0

funziona, questa soluzione ha il mio voto concordo sul fatto che conda potrebbe essere disattivato in un altro modo un cambiamento il suo nome non sembra una grande idea, lasciate che il conda da solo !! –

1

Come io non ho abbastanza reputazione per aggiungere un commento: suggerimento di Thomas Capote va bene (thx 4 che), ad eccezione "zsh" non ha un opzione "-t" per il build-in comando "tipo". Pertanto il suo necessario aggiungere un'altra dichiarazione condizionale per ottenere il risultato desiderato per "NAMETYPE":

# Anaconda workaround for "source deactivate" message: 
# Start of workaround: 
#type deactivate >/dev/null 2>&1 
#if [ $? -eq 0 ] 
if [ -n $ZSH_VERSION ] ; then 
    nametype="$(type -w deactivate)" 
else 
    nametype="$(type -t deactivate)" 
fi 
if [ "${nametype##* }" == "function" ] 
# End of workaround 

Speranza che aiuta altri utenti zsh.

+0

Puoi suggerire una modifica alla risposta originale o postare un'altra risposta con abbastanza dettagli per essere una risposta completa. Ma pubblicare un commento come risposta non è sicuramente una buona idea. Non ho contrassegnato il tuo post perché non penso sia necessario un commento, penso che potrebbe essere riformulato come risposta. – Nima