Cambiar el nombre de una carpeta virtualenv sin romperla

162

He creado una carpeta e inicializado una instancia virtualenv en ella.

$ mkdir myproject
$ cd myproject
$ virtualenv env

Cuando ejecuto (env)$ pip freeze, muestra los paquetes instalados como debería.

Ahora quiero cambiar el nombre myproject/a project/.

$ mv myproject/ project/

Sin embargo, ahora cuando corro

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

dice que pip no está instalado. ¿Cómo cambio el nombre de la carpeta del proyecto sin romper el entorno?

Riley Watkins
fuente
1
Esta pregunta es antigua y ya tiene una respuesta, pero tengo que preguntarme, ¿por qué el OP no pudo simplemente mover el virtualenv de regreso a donde estaba? Obviamente, eso no resuelve el deseo de mover / cambiar el nombre, pero ¿eso no restauraría un virtualenv funcional, o ya está irremediablemente roto?
Malik A. Rumi
2
Sí, tiene razón, repararía el entorno virtual, pero no resolvería el problema.
Florian
Noviembre de 2019, Python3. La mejor solución para mí es describir en aarongorka.com/blog/portable-virtualenv
Samir Sadek

Respuestas:

148

Debe ajustar su instalación para usar rutas relativas. virtualenvproporciona para esto con la --relocatableopción. De los documentos :

Normalmente los entornos están vinculados a una ruta específica. Eso significa que no puede mover un entorno o copiarlo a otra computadora. Puede arreglar un entorno para hacerlo reubicable con el comando:

$ virtualenv - ENV reubicable

NOTA: ENV es el nombre del entorno virtual y debe ejecutarlo desde fuera del directorio ENV.

Esto hará que algunos de los archivos creados por setuptools o distribuya utilicen rutas relativas, y cambiará todos los scripts para que activen_activar_esto.py en lugar de usar la ubicación del intérprete de Python para seleccionar el entorno.

Nota: debe ejecutar esto después de haber instalado los paquetes en el entorno. Si hace que un entorno sea reubicable, luego instale un nuevo paquete, debe ejecutar virtualenv --relocatable nuevamente.

ire_and_curses
fuente
2
advertencia: Cambiar un entorno a reubicable hace más que simplemente permitirle mover la carpeta. (vea la Nota: copiado de los documentos) ... puede tener efectos secundarios.
Ben Roberts
77
La opción --relocatable actualmente tiene varios 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. Además, esto no hace que sus paquetes sean multiplataforma. Puede mover el directorio, pero solo se puede usar en otras computadoras similares.
The Demz
1
@TheDemz grep -EIr '\Wold_venv_name\W' /path/to/new_venvayudará a encontrar cualquier shabangs que usen el antiguo venv, pero no es una verificación completa del venv reubicado.
encimeras
2
Además, tendrá que editar el .projectarchivo virtualenvwrapper , que contiene la ruta al código fuente que depende de virtualenv, suponiendo que está usando virutalenvwrapper y también ha cambiado el nombre del directorio del proyecto para que coincida con el nuevo virtualenv.
placas
Tuve que desactivar virtualenv antes de ejecutar esto.
antonagestam
108

Creo que "saber por qué" es más importante que "saber cómo" . Entonces, aquí hay otro enfoque para solucionar esto.

Cuando ejecuta . env/bin/activate, en realidad ejecuta los siguientes comandos (usando, /tmppor ejemplo):

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

Sin embargo, sólo ha cambiado el nombre myprojecta project, por lo que no se pudo ejecutar comandos. Es por eso que dice pip is not installed, porque no ha instalado pipen el entorno global del sistema y su virtualenv pipno se obtiene correctamente.

Si desea arreglar esto manualmente, esta es la forma:

  1. Con su editor favorito como Vim, modifique /tmp/project/env/bin/activategeneralmente en la línea 42:

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

  2. Modificar /tmp/project/env/bin/pipen la línea 1:

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

Después de eso, active su entorno virtual envnuevamente y verá que pipha vuelto.

holys
fuente
66
Si se desea cambiar manualmente las rutas, debe tenerse en cuenta que hay más de dos archivos codificados. Encontrar a todos ellos con algo como: grep -iHnR venv-name /path/to/venv-name | grep -v "^Binary file" | grep -i venv-name. De hecho, noté que en una de mis instancias de Django, muchos de los paquetes tenían la "ruta al sh-bang de Python".
Kevin
Esto me ayudó mucho. Definitivamente necesitaba saber por qué ... ¡Gracias!
Jarvis
En contraste con el comentario anterior de Keven, encuentro que editar estas dos líneas me resuelve todos los problemas con respecto a moverme virtualenv. Quizás haya algún caso de uso que no esté usando y, por lo tanto, no encuentre el problema.
Deleet
¡Rasca eso! Hoy me encontré con un problema: ipython no funcionaría dentro del virtualenv. Para resolverlo, edité el encabezado bash (¿cómo se llama?) En el ipythonarchivo y luego funcionó bien.
Deleet
Hmm, esto no está funcionando para mí, y parece que mi script de activación no tiene la Línea 1 a la que se hace referencia aquí en el Paso 2. ¿Ha cambiado algo?
Evan Zamir
40

NOTA: Como @jb. señala, esta solución solo se aplica a s (re) creados fácilmente virtualenv. Si un entorno tarda varias horas en instalar esta solución, no se recomienda


Virtualenvs son geniales porque son fáciles de hacer y cambiar; evitan que te bloquees en una sola configuración. Si conoce los requisitos del proyecto, o puede obtenerlos, haga un nuevovirtualenv :

  • Crear un requirements.txtarchivo

    (env)$ pip freeze > requirements.txt

    • Si no puede crear el requirements.txtarchivo, verifique env/lib/pythonX.X/site-packagesantes de eliminar el original env.
  • Eliminar lo existente (env)

    deactivate && rm -rf env

  • Cree uno nuevo virtualenv, actívelo e instale requisitos

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


Alternativamente, use virtualenvwrapper para hacer las cosas un poco más fáciles ya que todos los virtualenv se mantienen en una ubicación centralizada

$(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
fuente
66
Bueno, para algunas personas pip install -r requirements.txtlleva un par de horas (compilar extensiones C de terceros en raspberry pi).
jb.
44
Tal vez sea cierto, pero eso me parece un caso marginal. Sigo pensando que esta puede ser una solución viable para muchos casos.
bnjmn
Sí, muchos proyectos (el sitio web de Django, por ejemplo) solo tardan 30 segundos en instalar todo, incluso si tienen un par de docenas de dependencias (siempre que descargue todo primero y use '--no-index --find-links = downloadDir' )
Jonathan Hartley
1
@bnjmn, el one-liner virtualenv env && pip install -r requirements.txtNO instalará los requisitos en el nuevo entorno porque no lo activa
Yarin
1
@Yarin Gracias por señalar eso. Lo extrañé totalmente, siendo virtualenv-wrapperyo mismo usuario (que se activa automáticamente en la creación). He actualizado mi respuesta para incluir la activación con la virtualenvesperanza de evitar cualquier confusión.
bnjmn
28

Siempre instalo virtualenvwrapper para ayudar. Desde el indicador de shell:

pip install virtualenvwrapper

Hay una manera documentada en los documentos de virtualenvwrapper: cpvirtualenv Esto es lo que haces. Asegúrese de estar fuera de su entorno y volver al indicador de shell. Escriba esto con los nombres requeridos:

cpvirtualenv oldenv newenv

Y luego, si es necesario:

rmvirtualenv oldenv

Para ir a tu newenv:

workon newenv
Microondas
fuente
1
La respuesta de Afrowave realmente debería ser el método aceptado.
Jaxian
Esto solo funciona si uno está usando virtualenvwrapper, no solo virtualenv. Esta respuesta de @ryankdwyer es mejor.
LS
Edité mi respuesta para reflejar que uno debería instalar 'virtualenvwrapper'. Suponiendo que los entornos virtuales de cambio de nombre suceden mucho, recomendaría de esta manera.
Afrowave
Aunque se basa en virtualenvwrapper, es el más simple. Y funciona bien.
blasrodri
17

Puede solucionar su problema siguiendo estos pasos:

  1. renombra tu directorio
  2. vuelva a ejecutar esto: $ virtualenv ..\path\renamed_directory
  3. virtualenv corregirá las asociaciones de directorio mientras deja sus paquetes en su lugar
  4. $ scripts/activate
  5. $ pip freeze para verificar que sus paquetes estén en su lugar
  6. Una advertencia importante, si tiene dependencias de ruta estática en archivos de script en su directorio virtualenv, tendrá que cambiarlas manualmente.
ryankdwyer
fuente
1
Esta fue una muy buena solución para mí. Dado que esta solución puede evitar algunos de los problemas asociados --relocatable, creo que esta solución es mejor que la respuesta aceptada. Hasta ahora, he notado que muchos .pycarchivos _new_name_/lib/python2.7todavía se refieren _old_name_. Sin embargo, eso no parece afectar cómo funciona mi entorno. Quizás la única solución mejor es usar virtualenvwrappero algunas de las otras utilidades mencionadas entre las respuestas aquí. Al menos esta solución no requiere instalar programas adicionales.
LS
¡Funciona de maravilla!
AmirHossein
13

Otra forma de hacerlo que funcionó para mí muchas veces sin problemas es virtualenv-clone :

pip install virtualenv-clone
virtualenv-clone old-dir/env new-dir/env
Antony Hatchkins
fuente
Esto debe ser marcado como la mejor respuesta. ¡Manos abajo! Tomó algún tiempo clonar, así que tengan paciencia, muchachos.
Amitrajit Bose
virtualenv-clone no actualiza la solicitud. Tenía que ir a hacer eso manualmente. Aparte de eso es genial.
user3667349
5

(dentro de la carpeta del proyecto)

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

No olvides desactivar y activar

Ignacio
fuente
Funciona bien; O para la ruta de Linux:sed -i "s|$old_dir|$new_dir|g" bin/*
Destroyica
sed -i '.original' 's/old_dir_name/new_dir_name/g' *para Mac
Alex
1

virtualenv --relocatable ENVNo es una solución deseable. Supongo que la mayoría de la gente quiere la capacidad de cambiar el nombre de un virtualenv sin efectos secundarios a largo plazo.

Así que he creado una herramienta simple para hacer precisamente eso. La página del proyecto para virtualenv-mv lo describe con un poco más de detalle, pero esencialmente puede usarlo virtualenv-mvcomo si fuera una implementación simple de mv(sin ninguna opción).

Por ejemplo:

virtualenv-mv myproject project

Sin embargo, tenga en cuenta que acabo de hackear esto. Podría romperse en circunstancias inusuales (por ejemplo, virtualenvs con enlaces simbólicos), así que tenga cuidado (haga una copia de seguridad de lo que no puede permitirse perder) y avíseme si encuentra algún problema.

Seis
fuente