¿Puedo mover un virtualenv?

89

Esta pregunta no es un duplicado.

No solo se trata de cambiar el nombre de un entorno virtual, sino de moverlo a un directorio diferente, incluido, potencialmente, el directorio de un usuario diferente.

Esto no es lo mismo que simplemente cambiar el nombre de un entorno virtual, especialmente para las personas que no están familiarizadas con los virtualenvs.

Si creo un virtualenv y lo muevo a una carpeta diferente, ¿seguirá funcionando?

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

... más tarde ese día, el entorno virtual SE MOVIÓ ...

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

Pregunta:

esto funcionara?

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

Me refiero a esto como una pregunta menos sobre la sabiduría de intentar esto (a menos que esa sabiduría sea graciosa, por supuesto), y más sobre si es posible. Realmente quiero saber si es posible hacerlo en Python 3, o si solo tengo que absorberlo y clonarlo.

¿Puedo simplemente mvun virtualenvasí sin tristeza? Quiero evitar la tristeza.

Nathan Basanese
fuente

Respuestas:

69

Si. Es posible moverlo en la misma plataforma. Puede utilizarlo --relocatableen un entorno existente.

De --help:

--relocatable - Hacer que un entorno virtualenv EXISTENTE sea reubicable. Esto corrige los scripts y hace que todos los archivos .pth sean relativos.

SIN EMBARGO, esto NO parece cambiar el activatescript, sino que solo cambia los scripts pip*y easy_install*. En el activatescript, la $VIRTUAL_ENVvariable de entorno codificada como original /path/to/original/venv. La $VIRTUAL_ENVvariable se utiliza para establecer el PATHde su entorno activa también, por lo que debe ser cambiado en base a la nueva ubicación con el fin de llamar pythony pipetc, sin ruta absoluta.

Para solucionar este problema, puede cambiar la $VIRTUAL_ENVvariable de entorno en el activatescript (por ejemplo, usando sed), y todo debería estar listo.

Un ejemplo de uso:

$ 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

Hurra, ahora puede instalar cosas y cargarlas en su entorno virtual recién ubicado.

hilcharge
fuente
//, Hm. Esto no parece terminar haciendo que estos sean reubicables. Sigo recibiendo algún error acerca de que no son archivos de script "normales".
Nathan Basanese
7
"La opción --relocatable actualmente tiene una serie de problemas y no se garantiza que funcione en todas las circunstancias. Es posible que la opción quede obsoleta en una versión futura de virtualenv " . (Énfasis mío) consulte la guía
BobTuckerman
1
Intenté esto en Windows y el error enumera todos los scripts (* .py, * .bat, * .ps1) en el Scriptsdirectorio (equivalente a binen * nix) y dice algo como activate.ps1 cannot be made relative (it's not a normal script that starts with #!c:\..python.exe.básicamente quejarse de que el hash-bang en el archivo El encabezado no es el python.exe actual de virtualenv, es del que lo moví, fácil de arreglar. Miré en ese elegante guión y de todos modos ya descubre su propio camino, bueno. Algunos de los otros scripts tampoco se basan en rutas (por ejemplo, deactivate.bat), así que en resumen, esto funciona.
Davos
2
@NathanBasanese, el mensaje activate.ps1 cannot be made relativepuede ignorarse porque ese script ya es relativo. El mensaje no es útil en Windows, porque los scripts no usan #!directivas como en Linux para decirle al shell qué aplicación debe ejecutarlo. El activate.batno quede modificada, pero no se utiliza (al menos en las ventanas 10, llamando a activatelos lanzamientos de la secuencia de comandos Posh) por lo que no yo no tenía necesidad de editar las secuencias de comandos. El problema es pip.execuál tiene una ruta a Python codificada y necesita ser editada con un editor hexadecimal, o simplemente una reinstalación.
Davos
3
@Sgedda En retrospectiva, diría que no hagas esto. Sus entornos de Python deben ser fácilmente recreables usando como mínimo pip freezeun archivo de requisitos para que pueda reinstalar fácilmente todos sus paquetes, docker (funciona bien con virtualenv instalado), conda, pyenv o algunas otras herramientas. Debería poder crear y destruir entornos como una infraestructura inmutable, no deberían ser valiosos.
Davos
15

Para Python 3.3+ (con un nuevo venvmódulo integrado)

Respuesta corta (independientemente de la versión):

  • No existe una forma limpia y directa de mover un entorno virtual
  • Recrea, es fácil !!


Respuesta larga:

A partir de Python v3.3, se virtualenvha convertido en un módulo incorporado llamado venv.

La --relocatableopción mencionada en otras respuestas no se ha incluido en venv, y actualmente no existe una forma buena y segura que conozca de cambiar el nombre o reubicar un entorno virtual de Python.

Sin embargo, existe una forma bastante sencilla de simplemente recrear un entorno virtual, con todos sus paquetes instalados actualmente. Consulte esta respuesta o consulte la sección a continuación para obtener información sobre cómo recrear un entorno virtual. Durante el proceso, puede recrear el nuevo entorno en cualquier lugar y con el nombre que desee. O consulte la sección a continuación para conocer el proceso.

En esa respuesta, menciona algunos otros paquetes de terceros que pueden admitir cambios de nombre o movimientos directos. Si está decidido a buscar una forma de mover un entorno virtual intacto, podría investigar si esos también funcionan venv.

Nota: En esa respuesta, se centra en virtualenv, en lugar de venv. Vea a continuación cómo traducir.



venvvs virtualenvsintaxis de comando anterior

El comando a utilizar venves:

python -m venv

en lugar de solo virtualenv, que se instala como un comando en el paquete original. Donde "python" se refiere a cómo ejecuta su ejecutable de python, que podría ser una variedad de cosas, como:

  1. python
  2. pyo py -3.7similar ( Python Launcher para Windows para Python 3.3+ y Windows solo por el momento)
  3. python3 (convención para entornos linux que instalan de forma dual python 2 y 3)
  4. Si tiene problemas, use la ruta absoluta al ejecutable de Python que desea ejecutar: p. c:\program files\python37\python.exe

Si no está seguro de qué versión se está ejecutando, siempre puede python --versionaveriguarlo.



Cómo recrear un entorno virtual

Crear / recrear un entorno virtual es fácil y debería convertirse en algo natural después de trabajar un rato con ellos. Este proceso refleja lo que haría para distribuir su script como un paquete (con sus dependencias) en la primera mitad, y luego lo que haría alguien para instalar su script / paquete para un mayor desarrollo.

Primero, obtenga una lista actualizada de lo que hay en el entorno virtual. Con él activo, obtenga la versión de Python que usa y guarde la lista de dependencias en un archivo.

  1. Úselo python --versioncon el entorno virtual activado para ver qué versión de Python está usando.

    • Esto es para mayor claridad: es posible que desee actualizar la versión de Python por varias razones, al menos a la última versión del parche
    • Por ejemplo, si el venv existente está usando Python v3.7.4, pero ahora v3.7.6 está fuera, use v3.7.6 en su lugar, que debería incluir solo seguridad y correcciones de errores sin interrupciones.
  2. Úselo python -m pip freeze > requirements.txtpara crear la lista de dependencias de paquetes actuales y colocarlas en el requirements.txtarchivo. Este comando funciona en Linux o Git Bash con seguridad, no estoy 100% seguro de Powershell o Command Line en Windows.

Ahora cree un nuevo entorno virtual y luego agregue las dependencias del anterior.

  1. Haga su nuevo venv.

    • Asegúrese de que está utilizando la versión correcta de python que desea instalar en venv.
    • Si desea que sea exactamente la misma versión de Python:
      • Ejecute Python directamente desde el entorno virtual actual (con él activado) y utilícelo pythoncomo comando
      • O use una ruta absoluta python.exeen la carpeta del entorno virtual
    • Para la nueva entrada de la carpeta venv en el comando:
      • Agregue una ruta absoluta o relativa a la ubicación de la carpeta final deseada.
      • Úselo python -m venv my_new_venvpara crear un nuevo entorno virtual en el directorio de trabajo actual en una nueva my_new_venvcarpeta.
      • El nombre de la carpeta venv será el nombre del venv (lo que aparece en el indicador cuando se activa).
  2. Instale sus dependencias desde el requirements.txtarchivo.

    • python -m pip install -r requirements.txt

Es posible que deba reinstalar los paquetes locales que están en modo de desarrollo.

Tenga en cuenta que si alguna vez necesita ver la ubicación específica en la que está instalado un paquete, use:

  • python -m pip list -v
  • La -vopción o "verbose" agregará información adicional sobre cada paquete que está instalado, incluida la ruta en la que está instalado. Esto es útil para asegurarse de que mantiene los paquetes instalados virtuales, del usuario y del sistema en orden.

En este punto, puede eliminar la antigua carpeta venv y todo el contenido. Recomiendo usar una GUI para eso: las eliminaciones de archivos a menudo son permanentes desde la línea de comandos de Linux, y un pequeño error tipográfico puede ser una mala noticia.

LightCC
fuente
¿No hay forma de copiar el estado de venv pip, es decir, sin tener que volver a descargar todas las bibliotecas con pip?
Aydo
No estoy seguro de la razón por la que querría hacerlo: ¿se debe a una situación de ancho de banda extremadamente bajo para Internet o una necesidad masiva de duplicar mucho? Creo que podría obtener todas las cremalleras de pypi y luego instalarlo localmente, pero no estoy al tanto de eso. Sé que puede configurar un servidor pip local para alojar paquetes.
LightCC
El problema (que estoy tratando de resolver) es que quiero ejecutar una secuencia de comandos de Python en una máquina que no permite que el tráfico de la red pip (o casi en cualquier lugar). Puedo poner archivos en él, pero no puede hablar con pip. Un caso de nicho seguro, pero exactamente por qué necesito mover estas cosas.
Richard Rast
@RichardRast Ese es un problema diferente, solo estoy respondiendo la pregunta original. Nota: existen soluciones para su problema (descargue paquetes como zip e instálelos localmente, ejecute un servidor espejo PyPi detrás de su firewall, etc.), pero esto no es correcto: Preguntas y respuestas para eso ..
LightCC
2
Puede crear ruedas a partir de todos sus paquetes con pip wheel . -w wheelsy luego reinstalar los paquetes en el nuevo entorno virtual conpip install --no-index --find-links /path/to/wheels/ -r requirements.txt
np8
7

El --relocatableargumento de virtualenvparece permitirle hacer esto.

Ruth Franklin
fuente
//, ¿Esto solo se basa en rutas relativas, o funciona de alguna manera?
Nathan Basanese
1
--relocatable funciona solo en entornos virtuales existentes. Ejecute virtualenv --relocatable my-python-venvDESPUÉS de que el entorno ya exista.
hilcharge
1
De --help: This fixes up scripts and makes all .pth files relative. No, no va a hacer bibliotecas independientes de la plataforma. Si desea moverlo a una plataforma diferente, deberá reinstalarlo en función de la Python local.
hilcharge
5
el módulo python3 venv no admite esta bandera
Nelson
7

PERO AY:

No, simplemente no puedes mv. Existen soluciones alternativas, pero podría ser más fácil de reinstalar.

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

... presiona entermucho con frustración, y lo siguiente funciona

$
$
$ pip3 search foaas

Excepto que no es de my-python-venv, ergo tristeza.

¿Quieres mvtu virtualenvy usarlo, de lo contrario sin modificar?

Respuesta corta:

Dejaré que Boromir lo diga, para que pueda dejarlo claro:

Bueno, no puedes .

Nathan Basanese
fuente
2
a menos que desee volverse sangriento y modificarlo adecuadamente: son los enlaces en los binarios en el contenedor los que causan el problema de movimiento. Si sabe de dónde viene, puede usar algo como find bin -type f -exec ex -sc "%s,${FROM},${PWD},g|x" {} \;asumir que su bin y lib están en su carpeta venv actual. Utilizo esto como una forma rápida y sucia de copiar y mover envs virtuales python3 con muchos paquetes pip instalados.
Paul Whipp
1
@PaulWhipp ¿Hay algún beneficio en usar ese comando en comparación con solo usarlo --relocatable? Además, Nathan, gran pregunta pero esta es una respuesta terrible. Aceptar tu propia respuesta siempre es un poco sesgado, a menos que esté bien escrito y enumere claramente las opciones, pero determinar que tú mismo sería subjetivo de todos modos.
Davos
1
@Davos --relocatable no funcionó para mí, pero habitualmente muevo python3 venvs pirateando los binarios y hasta ahora no he tenido ningún problema.
Paul Whipp
1
Estaba insinuando que debería cambiar aceptado a una respuesta diferente (es decir, no la suya) Quizás la elegida por la gente: D
Davos
3
La pregunta era "¿puedo simplemente mv un venv?", Y la respuesta es "no mv, simplemente no puedes , hay soluciones pero podría ser más fácil de reinstalar". Si esta fuera la respuesta principal, nos ahorraría a otros y a mí algo de tiempo.
Nickolay
5

Sí, esto debería ser posible si no ha hecho nada que dependa del directorio actual del virtualenv.

Sin embargo, si tiene la opción, lo mejor que puede hacer es crear un nuevo virtualenv y comenzar a usar el nuevo virtualenv en su lugar. Esta es la opción más segura y menos probable que cause problemas más adelante.

La documentación menciona que :

Cada virtualenv tiene información de ruta codificada en él,

Por ejemplo, si ha ejecutado setvirtualenvproject, no podrá cambiar al directorio correcto después de ejecutar, workon ...por lo que en ese caso deberá corregirlo manualmente.

En general, un virtualenv es poco más que un directorio con los archivos de intérprete de Python necesarios más los paquetes que necesita.

Simeon Visser
fuente
2

Usando respuestas de este y otros hilos sobre temas similares, hice un script bash que, ubicado y ejecutado dentro del directorio virtualenv , ayudará con sus movimientos virtualenv.

Después de hacerlo virtualenv --relocatable yourenv, deberá cambiar su VIRTUAL_ENVvariable cada vez que mueva el directorio, por lo que si no desea cambiarlo manualmente, use esto.

#!/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

Espero que ayude.

Gerbs
fuente
0

¡SÍ TU PUEDES! (En windows)

La solución es fácil, simplemente mueva su entorno virtual a cualquier lugar y luego edite activate.batdentro scripts\:

  1. Mover al entorno virtual al directorio deseado

  2. Haga clic derecho y edite activate.batubicado en venv_folder\scripts.

  3. Cambiar VIRTUAL_ENVvariable de:

     set VIRTUAL_ENV=C:\old_directory\venv_name
    

    dentro

     set VIRTUAL_ENV=C:\new_directory\venv_name
    
  4. Guarde el archivo por lotes editado, ¡y listo!

NOTA: Mi solución debería funcionar y guardar la windows usersconfiguración de nuevos entornos virtuales, dudo que esto funcione en otro sistema operativo ya que .bates deMS-DOS

kyle olodin
fuente
Cambiar old_directorya old_directory- ¿es un error tipográfico?
ack el
aww maldición, sí, gracias
kyle olodin