Distutils2 el posible futuro del empaquetado de aplicaciones en Python

Distutils (Python Distribution Utilities) es un módulo estándar de la biblioteca de python con el propósito de distribuir aplicaciones Python de forma sencilla. Es el módulo estándar para empaquetado de aplicaciones en Python.

Si has utilizado distutils en pequeños proyectos puede que haya sido suficiente para tus necesidades. Sin embargo, a medida que es necesario personalizar con más detalles la instalación o realizar funciones avanzadas, distutils resulta ser un módulo carente de algunas funcionalidades y con muchos pequeños detalles por mejorar. Es simple, pero limitado y no extensible de forma trivial.

En mi opinión, hay dos principales problemas en la forma en la que se distribuye aplicaciones y módulos python:

  • 1) Existen muchas formas de realizar la instalación de una distribución de paquetes Python y crea un estado de interoperabilidad difícil.
  • 2) No existe una API para conseguir información de las distribuciones de paquetes instaladas.

Alternativas

Están disponibles otras alternativas como Setuptools. Este proyecto nació para rellenar pequeñas funcionalidades olvidadas en distutils y explorar nuevas direcciones. Para algunas subcomunidades Setuptools es un estándar de facto. Pero actualmente su desarrollo no esta siendo mantenido (por inactividad en 2 años) y su uso esta en decadencia desde que no tiene soporte para python 3.x.

Posteriormente surgió Distribute. Es un fork como reemplazo de Setuptools iniciado por los mismos desarrolladores que sentían que el proyecto no avanzaba lo suficiente y pensaban que no era posible una evolución.

De este último grupo ha surgido una nueva biblioteca, llamada Distutils2. Iniciada desde la base de distutils y tomando las buenas ideas de Setuptools (discutidas fuertemente en PEPs como PEP 376, PEP 386), además de inspirarse en un instalador básico similar a pip.

Integración Distutils2

Distutils2 tenia como principal objetivo la integración como módulo nativo en la rama de Python 3.3 bajo el módulo packaging. Debido a problemas en su desarrollo esta semi-paralizado hasta Python 3.4 a la espera de acuerdos entre desarrolladores y fijación de objetivos aunque este cuenta con una buena cobertura de test y estabilidad.

Novedades

Compatibilidad con otros sistemas

Distutils2 Estado actual del empaquetado de aplicaciones Python
Estado actual del empaquetado de aplicaciones Python

Los módulos de Distutils2 están capacitados para funcionar con PyPI y los metadatos asociados en proyectos instalados. El objetivo a largo plazo es la coexistencia de proyectos escritos para Pip o Distribute puesto que usan los mismos estándares. Por ejemplo, esta iniciándose una remodelización de pip, llamada pip2 que debería comtemplar la coexistencia con distutils2.

Nuevos comandos de instalación

Distutils2 habilita nuevos comandos de instalación como:

  • test : un comando para ejecutar las pruebas del proyecto (idea inspirada en Setuptools).
  • upload_docs: un comando para subir la documentación a packages.python.org
  • check: previamente añadido, pero ha sido mejorado para que se realicen comprobaciones antes de liberar o subir un paquete. Comprueba los metadatos, cumplimiento de reglas reST en la descripción.
  • uninstall: es una función muy básica añadida en el módulo distutils2.util que permite desinstalar de forma sencilla la aplicación. Esta ha sido una petición muy demandada para python 3.3. Además se incluye una API para eliminar todos los archivos que no cambiaron o directorios vacíos. Por ejemplo, para listar una lista de todos los archivos posibles para desinstalar:
from distutils2.util import uninstall
uninstall('setuptools')

Grafico de dependencias

El módulo constructor de grafos de dependencias de paquetes analiza las dependencias entre varias distribuciones de paquetes y permite a través de una API de código crear un grafo representando las relaciones entre ellos. Se sirve de graphviz para realizar los gráficos desde lenguage DOT. Por ejemplo, este sería el aspecto más básico y sin personalizar de un paquete de dependencias con el nombre “bacon”.

Gráfico de dependencias generado
Gráfico de dependencias generado

Archivo de configuración

Distutils2 toma como primera opción el archivo distutils2.cfg además del setup.cfg para permitir la compatibilidad con antiguos archivos de configuración. Es posible por tanto configurar la instalación sin necesidad de setup.py y sólo usar setup.cfg. Por defecto, los archivos como README o README.txt además del setup.py no serán más incluidos en la opción de distribución de fuentes.

Generación del archivo de configuración

Editar los archivos de configuración desde cero puede resultar muy tedioso, por ello se ha ideado un script interactivo (mkcfg) que permite generar el archivo setup.cfg preguntando los datos esenciales.

Para ejecutarlo:

$ python -m distutils2.mkcfg

Hooks

Distutils2 permite ser extensible a través de comandos que se ejecutan antes y después de una opción (hooks). Los hooks son simples funciones python (u objetos invocables) que están especificados en el archivo de configuración usando los nombres completos.

Los hooks se ejecutan después de que las opciones sean leídas y antes y después del comando a ejecutar.  Un ejemplo de hook necesitaría inicialmente que el hook estuviera presente en la ruta de ejecución, es decir, en el directorio del setup.py. Se crea un archivo en python para el hook, por ejemplo myhoook.py para el comando de instalación:

def my_install_support_hook(install_cmd):
    print "Genial, acabas de instalar mi proyecto! Ahora visita mi web blablable.com para soporte."

Posteriormente se edita el archivo setup.cfg bajo la sección de comandos apropiadas para la instalación:

[install]
pre-hook.myproject = myhooks.my_install_support_hook

Nuevas keywords

En la función setup donde recibe todas las palabras claves como autor, email, version, etc se han añadido nuevas que faciliten un mayor control.

Sistema de logging mejorado

La primera versión de disutils incluye un modulo de depuración para mensajes de error e información que no utilizaba el módulo logging estándar de Python, es decir siguiendo el estilo del PEP 282. La nueva versión de distutils2 usa de forma nativa el módulo logging.

Instalación

Si te ha parecido interesante el módulo de Distutils2, probablemente estés muy interesado en probarlo e instalarlo.

Para instalarlo puedes seguir la guía de instalación o el tutorial que se ofrece desde la documentación

Para python 2.7 puedes probar a instalarlo desde pip:

$ sudo pip install distutils2

Para Python 3, necesitas instalar (en Ubuntu) pip con compatibilidad para python3 con el paquete python3-pip:

$ sudo apt-get install python3-pip

Y después instalarlo vía:

$ sudo pip install http://hg.python.org/distutils2/archive/python3.tar.bz2

Si estas interesado en ver el código, puedes clonar el repositorio Mercurial con:

$ hg clone http://hg.python.org/distutils2

Como contribuir

Los autores de Distutils2 animan a contribuir y realizar sprints para finalizar características pendientes y corregir fallos.

Fuentes