7. Extendiendo distutils
************************

Nota:

  Este documento está siendo conservado sólo hasta que la
  documentación de "setuptools" en
  https://setuptools.readthedocs.io/en/latest/setuptools.html cubra de
  forma independiente toda la información actualmente incluida acá.

Distutils se puede extender de diversas maneras. La mayoría de las
extensiones toman la forma de nuevos comandos o reemplazos de comandos
ya existentes. Se pueden escribir nuevos comandos para soportar nuevos
tipos de paquetes específicos de la plataforma, por ejemplo, mientras
que se pueden reemplazar comandos existentes para modificar los
detalles de cómo funciona dicho comando en un paquete.

La mayoría de las extensiones de distutils están hechas dentro de los
scripts "setup.py" donde se desea modificar los comandos existentes.
Muchos simplemente añaden algunas extensiones de archivo que deben
copiarse dentro de los paquetes, además de los archivos ".py", para
mayor comodidad.

La mayoría de las implementaciones de comandos distutils son subclases
de la clase "distutils.cmd.Command". Los nuevos comandos pueden
heredar directamente de "Command". Mientras que los comandos de
reemplazo a menudo derivan de la clase "Command" de manera indirecta,
subclasificando directamente el comando que están reemplazando. Se
requiere que los comandos deriven de "Command".


7.1. Integrando nuevos comandos
===============================

Existen diferentes formas de integrar nuevas implementaciones de
comandos en distutils. La más difícil es forzar la inclusión de nuevas
funciones en distutils y esperar (y requerir) una versión de Python
que brinde ese soporte. Esto es realmente complicado por muchas
razones.

La más común, y posiblemente la más lógica para casi todas las
necesidades, es incluir las nuevas implementaciones con su *script*
"setup.py" y hacer que la función "distutils.core.setup()" las
utilice:

   from distutils.command.build_py import build_py as _build_py
   from distutils.core import setup

   class build_py(_build_py):
       """Specialized Python source builder."""

       # implement whatever needs to be different...

   setup(cmdclass={'build_py': build_py},
         ...)

Este enfoque es más valioso sí las nuevas implementaciones deben
utilizarse para hacer uso de un paquete en particular, ya que todos
los interesados en el paquete deberán tener la implementación del
nuevo comando.

A partir de Python 2.4, hay una tercera opción disponible, destinada a
permitir agregar nuevos comandos que sean compatibles con los scripts
"setup.py" existentes, sin requerir modificaciones en la instalación
de Python. Se espera que esto permita que las extensiones de terceros
brinden soporte para sistemas de empaquetado adicionales, pero los
comandos pueden ser usados en los mismos casos en los que los comandos
de distutils son utilizados. Una nueva opción de configuración,
"command_packages" (opción de la línea de comandos "--command-
packages"), puede ser aplicada para especificar paquetes adicionales a
ser buscados para módulos que implementen comandos. Como todas las
opciones de distutils, esto puede especificarse en la línea de
comandos o en un archivo de configuración. Esta opción sólo se puede
configurar en la sección "[global]" de un archivo de configuración, o
antes de cualquier comando en la línea de comandos. Si se establece en
un archivo de configuración, se puede sobrescribir desde la línea de
comandos. Establecer una cadena de caracteres vacía como valor de esta
opción en la línea de comandos forzará el uso del valor
predeterminado. Esto nunca debería ser establecido en un archivo de
configuración proporcionado con un paquete.

Esta nueva opción puede ser usada para añadir cualquier cantidad de
número de paquetes a la lista de paquetes buscados para las
implementaciones de comandos; los nombres múltiples de paquetes deben
ser separados por comas. Cuando no se especifica, la búsqueda sólo se
realiza en el paquete "distutils.command". Sin embargo, cuando
"setup.py" se ejecuta con la opción "--command-packages
distcmds,buildcmds", se buscarán los paquetes "distutils.command",
"distcmds" y "buildcmds" en ese orden. Se espera que los nuevos
comandos se implementen en módulos con idéntico nombre que el comando
mediante clases que comparten el mismo nombre. Dado el ejemplo
anterior de la opción de línea de comandos, el comando
**bdist_openpkg** podría ser implementado por la clase
"distcmds.bdist_openpkg.bdist_openpkg" o por la clase
"buildcmds.bdist_openpkg.bdist_openpkg".


7.2. Añadiendo nuevos tipos de distribución
===========================================

Los comandos que crean distribuciones (archivos en el directorio
"dist/") necesitan añadir el par "(command, filename)" a
"self.distribution.dist_files" para que de este modo **upload** pueda
subirlo a PyPI. El elemento *filename* en el par no contiene
información de la ruta, solo el nombre del archive en sí. En el modo
ensayo, los pares aún deben ser añadidos para representar lo que se
habría creado.
