venv — Crear entornos virtuales

Propósito:Crear contextos de instalación y ejecución aislados.

Los entornos virtuales de Python, administrados por venv, están configurados para instalar paquetes y ejecutar programas de una manera que los aísle de otros paquetes instalados en el resto del sistema. Debido a que cada entorno tiene su propio ejecutable de intérprete y directorio para instalar paquetes, es fácil crear entornos configurados con varias combinaciones de Python y versiones de paquetes, todo en la misma computadora.

Crear Entornos

La interfaz de línea de comando principal para venv se basa en la capacidad de Python para ejecutar una función «main» en un módulo utilizando la opción -m.

$ python3 -m venv /tmp/demoenv

Se puede instalar una aplicación de línea de comandos pyvenv separada, dependiendo de cómo se construyó y empaquetó el intérprete de Python. El siguiente comando tiene el mismo efecto que el ejemplo anterior.

$ pyvenv /tmp/demoenv

Se prefiere usar -m venv porque requiere seleccionar explícitamente un intérprete de Python, por lo que no puede haber confusión sobre el número de versión o la ruta de importación asociada con el entorno virtual resultante.

Contenidos de un entorno virtual

Cada entorno virtual contiene un directorio bin, donde están instalados el intérprete local y las secuencias de comandos ejecutables, un directorio include para archivos relacionados con la construcción de extensiones C, y un directorio lib, con una ubicación separada de site-packages para instalar paquetes.

$ ls -F /tmp/demoenv

bin/
include/
lib/
pyvenv.cfg

El directorio predeterminado bin contiene secuencias de comandos de «activación» para varias variantes de shell de Unix. Se pueden usar para instalar el entorno virtual en la ruta de búsqueda del shell para garantizar que el shell recupere programas instalados en el entorno. No es necesario activar un entorno para usar programas instalados en él, pero puede ser más conveniente.

$ ls -F /tmp/demoenv/bin

activate
activate.csh
activate.fish
easy_install*
easy_install-3.6*
pip*
pip3*
pip3.6*
python@
python3@

En las plataformas que los admiten, se utilizan enlaces simbólicos en lugar de copiar los ejecutables como el intérprete de Python. En este entorno, pip se instala como una copia local pero el intérprete es un enlace simbólico.

Finalmente, el entorno incluye un archivo pyvenv.cfg con configuraciones que describen cómo se configura y debe comportarse el entorno. La variable home apunta a la ubicación del intérprete de Python donde se ejecutó venv para crear el entorno. include-system-site-packages es un booleano que indica si los paquetes instalados fuera del entorno virtual, a nivel del sistema, deberían ser visibles dentro del entorno virtual. Y version es la versión de Python utilizada para crear el entorno.

pyvenv.cfg
# pyvenv.cfg

home = /Library/Frameworks/Python.framework/Versions/3.6/bin
include-system-site-packages = false
version = 3.6.4

Un entorno virtual es más útil con herramientas como pip y setuptools disponibles para instalar otros paquetes, por lo que pyvenv los instala por defecto. Para crear un entorno sin estas herramientas, pasa --without-pip en la línea de comando.

Usar entornos virtuales

Los entornos virtuales se usan comúnmente para ejecutar diferentes versiones de programas o para probar una versión dada de un programa con diferentes versiones de sus dependencias. Por ejemplo, antes de actualizar de una versión de Sphinx a otra, es útil probar los archivos de documentación de entrada utilizando las versiones antiguas y nuevas. Para comenzar, crea dos entornos virtuales.

$ python3 -m venv /tmp/sphinx1
$ python3 -m venv /tmp/sphinx2

Luego instala las versiones de las herramientas para probar.

$ /tmp/sphinx1/bin/pip install Sphinx==1.3.6

Collecting Sphinx==1.3.6
  Using cached Sphinx-1.3.6-py2.py3-none-any.whl
Collecting Pygments>=2.0 (from Sphinx==1.3.6)
  Using cached Pygments-2.2.0-py2.py3-none-any.whl
Collecting sphinx-rtd-theme<2.0,>=0.1 (from Sphinx==1.3.6)
  Using cached sphinx_rtd_theme-0.2.4-py2.py3-none-any.whl
Collecting babel!=2.0,>=1.3 (from Sphinx==1.3.6)
  Using cached Babel-2.5.3-py2.py3-none-any.whl
Collecting alabaster<0.8,>=0.7 (from Sphinx==1.3.6)
  Using cached alabaster-0.7.10-py2.py3-none-any.whl
Collecting Jinja2>=2.3 (from Sphinx==1.3.6)
  Using cached Jinja2-2.10-py2.py3-none-any.whl
Collecting docutils>=0.11 (from Sphinx==1.3.6)
  Using cached docutils-0.14-py3-none-any.whl
Collecting snowballstemmer>=1.1 (from Sphinx==1.3.6)
  Using cached snowballstemmer-1.2.1-py2.py3-none-any.whl
Collecting six>=1.4 (from Sphinx==1.3.6)
  Using cached six-1.11.0-py2.py3-none-any.whl
Collecting pytz>=0a (from babel!=2.0,>=1.3->Sphinx==1.3.6)
  Using cached pytz-2018.3-py2.py3-none-any.whl
Collecting MarkupSafe>=0.23 (from Jinja2>=2.3->Sphinx==1.3.6)
  Using cached MarkupSafe-1.0.tar.gz
Installing collected packages: Pygments, sphinx-rtd-theme, pytz,
babel, alabaster, MarkupSafe, Jinja2, docutils, snowballstemmer,
six, Sphinx
  Running setup.py install for MarkupSafe: started
    Running setup.py install for MarkupSafe: finished with
status 'done'
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Pygments-2.2.0
Sphinx-1.3.6 alabaster-0.7.10 babel-2.5.3 docutils-0.14
pytz-2018.3 six-1.11.0 snowballstemmer-1.2.1 sphinx-rtd-
theme-0.2.4

$ /tmp/sphinx2/bin/pip install Sphinx==1.4.4

Collecting Sphinx==1.4.4
  Using cached Sphinx-1.4.4-py2.py3-none-any.whl
Collecting imagesize (from Sphinx==1.4.4)
  Using cached imagesize-1.0.0-py2.py3-none-any.whl
Collecting Pygments>=2.0 (from Sphinx==1.4.4)
  Using cached Pygments-2.2.0-py2.py3-none-any.whl
Collecting snowballstemmer>=1.1 (from Sphinx==1.4.4)
  Using cached snowballstemmer-1.2.1-py2.py3-none-any.whl
Collecting alabaster<0.8,>=0.7 (from Sphinx==1.4.4)
  Using cached alabaster-0.7.10-py2.py3-none-any.whl
Collecting Jinja2>=2.3 (from Sphinx==1.4.4)
  Using cached Jinja2-2.10-py2.py3-none-any.whl
Collecting docutils>=0.11 (from Sphinx==1.4.4)
  Using cached docutils-0.14-py3-none-any.whl
Collecting babel!=2.0,>=1.3 (from Sphinx==1.4.4)
  Using cached Babel-2.5.3-py2.py3-none-any.whl
Collecting six>=1.4 (from Sphinx==1.4.4)
  Using cached six-1.11.0-py2.py3-none-any.whl
Collecting MarkupSafe>=0.23 (from Jinja2>=2.3->Sphinx==1.4.4)
  Using cached MarkupSafe-1.0.tar.gz
Collecting pytz>=0a (from babel!=2.0,>=1.3->Sphinx==1.4.4)
  Using cached pytz-2018.3-py2.py3-none-any.whl
Installing collected packages: imagesize, Pygments,
snowballstemmer, alabaster, MarkupSafe, Jinja2, docutils, pytz,
babel, six, Sphinx
  Running setup.py install for MarkupSafe: started
    Running setup.py install for MarkupSafe: finished with
status 'done'
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Pygments-2.2.0
Sphinx-1.4.4 alabaster-0.7.10 babel-2.5.3 docutils-0.14
imagesize-1.0.0 pytz-2018.3 six-1.11.0 snowballstemmer-1.2.1

Entonces es posible ejecutar las diferentes versiones de Sphinx desde los entornos virtuales por separado, para probarlas con los mismos archivos de entrada.

$ /tmp/sphinx1/bin/sphinx-build --version

Sphinx (sphinx-build) 1.3.6

$ /tmp/sphinx2/bin/sphinx-build --version

Sphinx (sphinx-build) 1.4.4

Ver también