# 1. Una introducción a Distutils

Nota

Este documento se conserva únicamente hasta que la documentación de `setuptools` en https://setuptools.readthedocs.io/en/latest/setuptools.html cubra de forma independiente toda la información relevante que se incluye actualmente aquí.

Este documento cubre el uso de Distutils para distribuir módulos de Python, concentrándose en el rol de desarrollador/distribuidor: si está buscando información de como instalar módulos Python, debe consultar el capítulo Instalación de Módulos de Python (versión antigua).

## 1.1. Conceptos y Terminología

Usar Distutils es muy simple, tanto para desarrolladores de módulos como para usuarios/administradores que instalan módulos de terceros. Como desarrollador, sus responsabilidades (¡además de escribir código sólido, bien documentado y probado, por supuesto!) son:

- escribir un script de configuración (`setup.py` por convención)

- (opcional) escribir un archivo de configuración

- crear una distribución fuente

- (opcional) crear una o más distribuciones construidas (binarias)

Cada una de estas tareas está cubierta en este documento.

No todos los desarrolladores de módulos tienen acceso a una multitud de plataformas, por lo que no siempre es factible esperar que creen una multitud de distribuciones. Es de esperar que surjan intermediarios, llamados empaquetadores, para ayudar con esta necesidad. Los empaquetadores tomarán distribuciones de origen lanzadas por desarrolladores de módulo, las compilaran en una o más plataformas, y lanzaran las distribuciones resultantes. Así, los usuarios en las plataformas más populares podrán instalar las distribuciones de módulos Python más populares de la manera más natural para su plataforma, sin tener que ejecutar un solo script de configuración o compilar una línea de código.

## 1.2. Un ejemplo simple

El script de configuración suele ser simple, dado que está escrito en Python, no hay límite para lo que puede hacerse con él, aunque debe tener cuidado al poner operaciones arbitrariamente costosas en el script de configuración. A diferencia de, por ejemplo, las secuencias de comandos de configuración de estilo Autoconf, la secuencia de comandos de configuración se puede ejecutar varias veces en el transcurso de la construcción e instalación de la distribución de su módulo.

Si todo lo que quiere hacer es distribuir un módulo llamado `foo`, contenido en un archivo `foo.py`, entonces el script de configuración puede ser tan simple como esto:

    from distutils.core import setup
    setup(name='foo',
          version='1.0',
          py_modules=['foo'],
          )

Algunas observaciones:

- la mayoría de la información que proporcione a Distutils se proporciona como argumentos keyword a la función `setup()`

- esos argumentos keyword se dividen en dos categorías: metadatos del paquete (nombre, número de versión) e información sobre el contenido del paquete (una lista de módulos Python, en este caso)

- módulos son especificados por nombre de módulo, no por nombre de archivo (lo mismo aplica para paquetes y extensiones)

- se recomienda que proporcione un poco más de metadatos, en particular nombre, dirección de correo electrónico y URL para el proyecto (consulte la sección Escribir el script de configuración para ver un ejemplo)

Para crear una distribución fuente para este módulo, debe crear un script de configuración, `setup.py`, que contenga el código de arriba, y ejecute este comando en la terminal:

    python setup.py sdist

En Windows, abra una ventana de símbolo de sistema (Inicio —> Accesorios) y cambie el comando a:

    setup.py sdist

sdist creará un archivo de almacenamiento (por ejemplo, tarball en Unix, archivo ZIP en Windows) que contiene su script de configuración `setup.py`, y su módulo `foo.py`. El archivo de almacenamiento se llamará `foo-1.0.tar.gz` (o `.zip`), y se descomprimirá en un directorio `foo-1.0`.

Si un usuario final desea instalar su módulo `foo`, lo que tiene que hacer es descargar `foo-1.0.tar.gz` (o `.zip`), descomprimirlo, y—del directorio `foo-1.0`—ejecutar

    python setup.py install

que finalmente copiará `foo.py` en el directorio apropiado para módulos de terceros en su instalación de Python.

Este sencillo ejemplo demuestra algunos conceptos fundamentales de Distutils. Primero, tanto los desarrolladores como los instaladores tienen la misma interfaz básica, es decir, el script de configuración. La diferencia es qué comandos de Distutils usan: el comando sdist es casi exclusivamente para desarrolladores de módulos, mientras que install es más frecuente para los instaladores (aunque la mayoría de los desarrolladores querrán instalar su propio código ocasionalmente )

Otros formatos de distribución útiles son RPM, implementados por el comando bdist_rpm, Solaris pkgtool (bdist_pkgtool) y HP-UX swinstall (:command:` bdist_sdux`). Por ejemplo, el siguiente comando creará un archivo RPM llamado `foo-1.0.noarch.rpm`:

    python setup.py bdist_rpm

(El comando bdist_rpm utiliza el ejecutable rpm, por lo tanto, esto debe ejecutarse en un sistema basado en RPM como Red Hat Linux, SuSE Linux o Mandrake Linux.)

Puede averiguar qué formatos de distribución están disponibles en cualquier momento ejecutando

    python setup.py bdist --help-formats

## 1.3. Terminología general de Python

Si está leyendo este documento, probablemente tenga una buena idea de qué son los módulos, extensiones, etc. Sin embargo, solo para asegurarnos de que todos operen desde un punto de partida común, ofrecemos el siguiente glosario de términos comunes de Python:

módulo

  la unidad básica de reutilización de código en Python: un bloque de código importado por algún otro código. Aquí nos interesan tres tipos de módulos: módulos Python puros, módulos de extensión y paquetes.

módulo Python puro

  un módulo escrito en Python y contenido en un solo archivo `.py` (y posiblemente asociado con archivos `.pyc`). A veces se lo denomina «módulo puro».

módulo de extensión

  un módulo escrito en el lenguaje de bajo nivel de la implementación de Python: C/C++ para Python, Java para Jython. Típicamente contenido en un único archivo precompilado cargable dinámicamente, ejemplo, un archivo de objeto compartido (:file: .so`) para extensiones de Python en Unix, una DLL (dada la extensión `.pyd`) para extensiones de Python en Windows, o un archivo de clase Java para extensiones de Jython. (Tenga en cuenta que actualmente, Distutils solo maneja extensiones C/C++ para Python.)

paquete

  un módulo que contiene otros módulos; típicamente contenido en un directorio en el sistema de archivos y diferenciado de otros directorios por la presencia de un archivo `__init __. py`.

paquete raíz

  la raíz de la jerarquía de paquetes. (Esto no es realmente un paquete, ya que no tiene un archivo `__init __.py`. Pero tenemos que llamarlo de alguna forma). La gran mayoría de la biblioteca estándar está en el paquete raíz, como muchos módulos de terceros pequeños e independientes que no pertenecen a una colección de módulos más grande. A diferencia de los paquetes regulares, los módulos en el paquete raíz se pueden encontrar en muchos directorios: de hecho, cada directorio listado en `sys.path` contribuye con módulos al paquete raíz.

## 1.4. Terminología específica de Distutils

Los siguientes términos se aplican más específicamente al dominio de distribución de módulos de Python utilizando Distutils:

distribución de módulo

  una colección de módulos de Python distribuidos como un único recurso descargable y destinado a ser instalados en masa. Ejemplos de algunas distribuciones de módulos conocidas son NumPy, SciPy, Pillow o mxBase. (Esto se llama paquete, excepto que ese término ya se ha tomado en el contexto de Python: una distribución de un solo módulo puede contener cero, uno o muchos paquetes de Python).

distribución pura del módulo

  una distribución de módulos que contiene solo módulos y paquetes de Python. A veces se lo denomina «distribución pura».

distribución de módulos no puros

  una distribución de módulo que contiene al menos un módulo de extensión. En ocasiones se denomina «distribución no pura».

distribución raíz

  el directorio de nivel superior del árbol fuente (o distribución fuente); el directorio donde `setup.py` existe. Generalmente `setup.py` se ejecutará desde este directorio.