2. Escribir el script de configuración
**************************************

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í.

El script de configuración es el centro de toda actividad en la
construcción, distribución e instalación de módulos utilizando
Distutils. El propósito principal del script de configuración es
describir la distribución de su módulo a Distutils, de modo que los
diversos comandos que operan en sus módulos hagan lo correcto. Como
vimos en la sección ejemplo simple de distutils anterior, el script de
configuración consiste principalmente en una llamada a "setup()", y la
mayoría de la información suministrada a Distutils por el
desarrollador del módulo se proporciona como argumentos de palabras
clave para "setup()".

Aquí hay un ejemplo un poco más complicado, que seguiremos en las
próximas secciones: el propio script de configuración de Distutils.
(Tenga en cuenta que aunque los Distutils se incluyen con Python 1.6 y
posteriores, también tienen una existencia independiente para que los
usuarios de Python 1.5.2 puedan usarlos para instalar otras
distribuciones de módulos. Se utiliza el propio script de
configuración de Distutils, que se muestra aquí). instalar el paquete
en Python 1.5.2.)

   #!/usr/bin/env python

   from distutils.core import setup

   setup(name='Distutils',
         version='1.0',
         description='Python Distribution Utilities',
         author='Greg Ward',
         author_email='gward@python.net',
         url='https://www.python.org/sigs/distutils-sig/',
         packages=['distutils', 'distutils.command'],
        )

Solo hay dos diferencias entre esto y la trivial distribución de un
archivo presentada en la sección ejemplo simple de distutils: más
metadatos y la especificación de módulos Python puros por paquete, en
lugar de por módulo. Esto es importante ya que los Distutils consisten
en un par de docenas de módulos divididos en (hasta ahora) dos
paquetes; Una lista explícita de cada módulo sería tediosa de generar
y difícil de mantener. Para obtener más información sobre los
metadatos adicionales, consulte la sección Metadatos adicionales.

Tenga en cuenta que los nombres de ruta (archivos o directorios)
proporcionados en el script de configuración deben escribirse
utilizando la convención de Unix, es decir, separados por barras.
Distutils se encargará de convertir esta representación neutral de la
plataforma en lo que sea apropiado en su plataforma actual antes de
usar el nombre de ruta. Esto hace que su script de configuración sea
portátil en todos los sistemas operativos, lo que, por supuesto, es
uno de los principales objetivos de Distutils. En este espíritu, todos
los nombres de ruta en este documento están separados por barras.

Esto, por supuesto, solo se aplica a los nombres de ruta asignados a
las funciones de Distutils. Si, por ejemplo, utiliza funciones
estándar de Python como "glob.glob()" o "os.listdir()" para
especificar archivos, debe tener cuidado al escribir código portátil
en lugar de codificar separadores de ruta:

   glob.glob(os.path.join('mydir', 'subdir', '*.html'))
   os.listdir(os.path.join('mydir', 'subdir'))


2.1. Listado de paquetes completos
==================================

La opción "packages" le dice a Distutils que procese (compile,
distribuya, instale, etc.) todos los módulos de Python puros que se
encuentran en cada paquete mencionado en la lista de "packages". Para
hacer esto, por supuesto, debe haber una correspondencia entre los
nombres de los paquetes y los directorios en el sistema de archivos.
La correspondencia predeterminada es la más obvia, es decir, el
paquete "distutils" se encuentra en el directorio "distutils" en
relación con la raíz de distribución. Por lo tanto, cuando diga
"packages = ['foo']" en su secuencia de comandos de configuración,
promete que Distutils encontrará un archivo "foo/__init__.py" (que
podría estar escrito de manera diferente en su sistema , pero te haces
una idea) en relación con el directorio donde vive tu script de
configuración. Si no cumple esta promesa, Distutils emitirá una
advertencia pero de todos modos procesará el paquete roto.

Si usa una convención diferente para diseñar su directorio de origen,
no hay problema: solo tiene que proporcionar la opción "package_dir"
para informar a los Distutils sobre su convención. Por ejemplo,
supongamos que mantiene toda la fuente de Python en "lib", de modo que
los módulos en el "paquete raíz" (es decir, no en ningún paquete)
estén en "lib", módulos en el paquete "foo" está en archivo "lib/foo",
y así sucesivamente. Entonces pondrías

   package_dir = {'': 'lib'}

en tu script de configuración. Las claves de este diccionario son
nombres de paquetes, y un nombre de paquete vacío representa el
paquete raíz. Los valores son nombres de directorio relativos a su
raíz de distribución. En este caso, cuando dices "packages = ['foo']",
estás prometiendo que el archivo "lib/foo/__init__.py" existe.

Otra posible convención es colocar el paquete "foo" directamente en
"lib", el paquete "foo.bar" en "lib/bar", etc. Esto se escribiría en
el script de configuración como

   package_dir = {'foo': 'lib'}

Una entrada "package: dir" en el diccionario "package_dir" se aplica
implícitamente a todos los paquetes debajo de *package*, por lo que el
caso "foo.bar" se maneja automáticamente aquí. En este ejemplo, tener
"packages = ['foo', 'foo.bar']" le dice a los Distutils que busquen
"lib/__init__.py" y "lib/bar/__init__.py". (Tenga en cuenta que,
aunque "package_dir" se aplica de forma recursiva, debe enumerar
explícitamente todos los paquetes en "packages": los Distutils *no*
escanearán recursivamente su árbol de origen buscando cualquier
directorio con un archivo "__init__.py".)


2.2. Listado de módulos individuales
====================================

Para una distribución de módulos pequeños, es posible que prefiera
enumerar todos los módulos en lugar de enumerar los paquetes,
especialmente el caso de un solo módulo que va en el "paquete raíz"
(es decir, ningún paquete). Este caso más simple se mostró en la
sección Un ejemplo simple; Aquí hay un ejemplo un poco más complicado:

   py_modules = ['mod1', 'pkg.mod2']

Esto describe dos módulos, uno en el paquete "raíz", el otro en el
paquete "pkg". Nuevamente, el diseño predeterminado del
paquete/directorio implica que estos dos módulos se pueden encontrar
en "mod1.py" y "pkg/mod2.py", y que "pkg/__init__.py" existe también.
Y nuevamente, puede anular la correspondencia paquete/directorio
utilizando la opción "package_dir".


2.3. Describiendo módulos de extensión
======================================

Así como escribir módulos de extensión Python es un poco más
complicado que escribir módulos Python puros, describirlos a Distutils
es un poco más complicado. A diferencia de los módulos puros, no basta
con enumerar módulos o paquetes y esperar que Distutils salga y
encuentre los archivos correctos; debe especificar el nombre de la
extensión, el (los) archivo (s) de origen y cualquier requisito de
compilación/enlace (incluir directorios, bibliotecas para enlazadores,
etc.).

Todo esto se realiza a través de otro argumento de palabra clave para
"setup()", la opción "ext_modules". "ext_modules" es solo una lista de
instancias "Extension", cada una de las cuales describe un único
módulo de extensión. Suponga que su distribución incluye una sola
extensión, llamada "foo" e implementada por "foo.c". Si no se
necesitan instrucciones adicionales para el compilador/enlazador,
describir esta extensión es bastante simple:

   Extension('foo', ['foo.c'])

La clase "Extension" se puede importar desde "distutils.core" junto
con "setup()". Por lo tanto, el script de configuración para una
distribución de módulo que contiene solo esta extensión y nada más
podría ser:

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

La clase "Extension" (en realidad, la maquinaria de construcción de
extensiones subyacente implementada por el comando **build_ext**)
admite una gran flexibilidad al describir las extensiones de Python,
que se explica en las siguientes secciones.


2.3.1. Nombres de extensión y paquetes
--------------------------------------

El primer argumento para el constructor "Extension" es siempre el
nombre de la extensión, incluidos los nombres de los paquetes. Por
ejemplo,

   Extension('foo', ['src/foo1.c', 'src/foo2.c'])

describe una extensión que vive en el paquete raíz, mientras que

   Extension('pkg.foo', ['src/foo1.c', 'src/foo2.c'])

describe la misma extensión en el paquete "pkg". Los archivos fuente y
el código objeto resultante son idénticos en ambos casos; la única
diferencia es dónde en el sistema de archivos (y, por lo tanto, dónde
en la jerarquía del espacio de nombres de Python) vive la extensión
resultante.

Si tiene varias extensiones, todas en el mismo paquete (o todas en el
mismo paquete base), use el argumento de palabra clave "ext_package"
para "setup()". Por ejemplo,

   setup(...,
         ext_package='pkg',
         ext_modules=[Extension('foo', ['foo.c']),
                      Extension('subpkg.bar', ['bar.c'])],
        )

compilará "foo.c" a la extensión "pkg.foo", y "bar.c" a
"pkg.subpkg.bar".


2.3.2. Extensión de archivos fuente
-----------------------------------

El segundo argumento para el constructor "Extension" es una lista de
archivos fuente. Dado que Distutils actualmente solo admite
extensiones C, C++ y Objective-C, estos normalmente son archivos
fuente C/C++/Objective-C. (Asegúrese de usar las extensiones
apropiadas para distinguir los archivos fuente de C++ ".cc" y ".cpp"
que parecen ser reconocidos por los compiladores de Unix y Windows).

Sin embargo, también puede incluir archivos de interfaz SWIG (".i") en
la lista; el comando **build_ext** sabe cómo manejar las extensiones
SWIG: ejecutará SWIG en el archivo de interfaz y compilará el archivo
C/C++ resultante en su extensión.

A pesar de esta advertencia, las opciones para SWIG se pueden pasar
actualmente de esta manera:

   setup(...,
         ext_modules=[Extension('_foo', ['foo.i'],
                                swig_opts=['-modern', '-I../include'])],
         py_modules=['foo'],
        )

O en la línea de comandos como esta

   > python setup.py build_ext --swig-opts="-modern -I../include"

En algunas plataformas, puede incluir archivos que no sean de origen
procesados por el compilador e incluidos en su extensión. Actualmente,
esto solo significa archivos de texto de mensaje de Windows (".mc") y
archivos de definición de recursos (".rc") para Visual C ++. Estos
serán compilados en archivos de recursos binarios (".res") y
enlazados.


2.3.3. Opciones de preprocesador
--------------------------------

Tres argumentos opcionales para "Extension" le ayudarán si necesita
especificar directorios de inclusión para buscar o preprocesar macros
para definir/indefinir: "include_dirs", "define_macros" y
"undef_macros".

Por ejemplo, si su extensión requiere archivos de encabezado en el
directorio "include" bajo su raíz de distribución, use la opción
"include_dirs":

   Extension('foo', ['foo.c'], include_dirs=['include'])

Puede especificar directorios absolutos allí; si sabe que su extensión
solo se construirá en sistemas Unix con X11R6 instalado en "/usr",
puede salirse con

   Extension('foo', ['foo.c'], include_dirs=['/usr/include/X11'])

Debería evitar este tipo de uso no portátil si planea distribuir su
código: probablemente sea mejor escribir código C como

   #include <X11/Xlib.h>

Si necesita incluir archivos de encabezado de alguna otra extensión de
Python, puede aprovechar el hecho de que los archivos de encabezado se
instalan de manera coherente mediante el comando Distutils
**install_headers**. Por ejemplo, los archivos de encabezado Python
numéricos se instalan (en una instalación estándar de Unix) en
"/usr/local/include/python1.5/ Numerical". (La ubicación exacta
diferirá según la plataforma y la instalación de Python). Dado que el
directorio de inclusión de Python --- "/usr/local/include/python1.5"
en este caso --- siempre se incluye en ruta de búsqueda al construir
extensiones de Python, el mejor enfoque es escribir código C como

   #include <Numerical/arrayobject.h>

Sin embargo, si debe colocar el directorio "Numerical" en la ruta de
búsqueda del encabezado, puede encontrar ese directorio utilizando el
módulo Distutils "distutils.sysconfig":

   from distutils.sysconfig import get_python_inc
   incdir = os.path.join(get_python_inc(plat_specific=1), 'Numerical')
   setup(...,
         Extension(..., include_dirs=[incdir]),
         )

Aunque esto es bastante portátil, funcionará en cualquier instalación
de Python, independientemente de la plataforma, probablemente sea más
fácil escribir su código C de manera sensata.

Puede definir y no definir macros de preprocesador con las opciones
"define_macros" y "undef_macros". "define_macros" toma una lista de
tuplas "(name, value)", donde "name" es el nombre de la macro a
definir (una cadena de caracteres) y "value" es su valor: ya sea un
cadena de caracteres o "None". (Definir una macro "FOO" en "None" es
el equivalente de un simple "#define FOO" en su fuente C: con la
mayoría de los compiladores, esto establece "FOO" en la cadena "1".)
"undef_macros" es solo una lista de macros para indefinir.

Por ejemplo:

   Extension(...,
             define_macros=[('NDEBUG', '1'),
                            ('HAVE_STRFTIME', None)],
             undef_macros=['HAVE_FOO', 'HAVE_BAR'])

es el equivalente a tener esto en la parte superior de cada archivo
fuente C:

   #define NDEBUG 1
   #define HAVE_STRFTIME
   #undef HAVE_FOO
   #undef HAVE_BAR


2.3.4. Opciones de biblioteca
-----------------------------

También puede especificar las bibliotecas para enlazarlas al crear su
extensión y los directorios para buscar esas bibliotecas. La opción
"bibliotecas" es una lista de bibliotecas para enlazar, "library_dirs"
es una lista de directorios para buscar bibliotecas en el momento del
enlace, y "runtime_library_dirs" es una lista de directorios para
buscar compartidos (cargadas dinámicamente) bibliotecas en tiempo de
ejecución.

Por ejemplo, si necesita enlazar con bibliotecas que se sabe que están
en la ruta de búsqueda de biblioteca estándar en los sistemas de
destino:

   Extension(...,
             libraries=['gdbm', 'readline'])

Si necesita enlazar con bibliotecas en una ubicación no estándar,
deberá incluir la ubicación en "library_dirs":

   Extension(...,
             library_dirs=['/usr/X11R6/lib'],
             libraries=['X11', 'Xt'])

(Nuevamente, este tipo de construcción no portátil debe evitarse si
tiene la intención de distribuir su código.)


2.3.5. Otras opciones
---------------------

Todavía hay algunas otras opciones que se pueden usar para manejar
casos especiales.

La opción "optional" es booleana; si es cierto, una falla de
compilación en la extensión no abortará el proceso de compilación,
sino que simplemente no instalará la extensión que falla.

La opción "extra_objects" es una lista de archivos de objetos que se
pasarán al enlazador. Estos archivos no deben tener extensiones, ya
que se usa la extensión predeterminada para el compilador.

"extra_compile_args" y "extra_link_args" se pueden usar para
especificar opciones de línea de comando adicionales para las líneas
de comando del compilador y enlazador respectivo.

"export_symbols" solo es útil en Windows. Puede contener una lista de
símbolos (funciones o variables) para exportar. Esta opción no es
necesaria cuando se crean extensiones compiladas: Distutils agregará
automáticamente "initmodule" a la lista de símbolos exportados.

La opción "depends" es una lista de archivos de los que depende la
extensión (por ejemplo, archivos de encabezado). El comando de
compilación llamará al compilador en las fuentes para reconstruir la
extensión si alguno de estos archivos se ha modificado desde la
compilación anterior.


2.4. Relaciones entre distribuciones y paquetes
===============================================

Una distribución puede relacionarse con paquetes de tres maneras
específicas:

1. Puede requerir paquetes o módulos.

2. Puede proporcionar paquetes o módulos.

3. Puede paquetes o módulos obsoletos.

Estas relaciones se pueden especificar utilizando argumentos de
palabras clave para la función "distutils.core.setup()".

Las dependencias en otros módulos y paquetes de Python se pueden
especificar proporcionando el argumento de palabra clave *requires* a
"setup()". El valor debe ser una lista de cadenas de caracteres. Cada
cadena especifica un paquete que se requiere y, opcionalmente, qué
versiones son suficientes.

Para especificar que se requiere cualquier versión de un módulo o
paquete, la cadena debe consistir completamente en el nombre del
módulo o paquete. Los ejemplos incluyen "'mymodule'" y
"'xml.parsers.expat'".

Si se requieren versiones específicas, se puede proporcionar una
secuencia de calificadores entre paréntesis. Cada calificador puede
consistir en un operador de comparación y un número de versión. Los
operadores de comparación aceptados son:

   <    >    ==
   <=   >=   !=

Estos se pueden combinar usando múltiples calificadores separados por
comas (y espacios en blanco opcionales). En este caso, todos los
calificadores deben coincidir; Se utiliza un AND lógico para combinar
las evaluaciones.

Veamos algunos ejemplos:

+---------------------------+------------------------------------------------+
| Expresión Requiere        | Explicación                                    |
|===========================|================================================|
| "==1.0"                   | Solo la versión "1.0" es compatible            |
+---------------------------+------------------------------------------------+
| ">1.0, !=1.5.1, <2.0"     | Cualquier versión posterior a "1.0" y anterior |
|                           | a "2.0" es compatible, excepto "1.5.1"         |
+---------------------------+------------------------------------------------+

Ahora que podemos especificar dependencias, también debemos poder
especificar qué proporcionamos que otras distribuciones pueden
requerir. Esto se hace usando el argumento de palabra clave *provides*
para "setup()". El valor de esta palabra clave es una lista de
cadenas, cada una de las cuales nombra un módulo o paquete Python, y
opcionalmente identifica la versión. Si no se especifica la versión,
se supone que coincide con la de la distribución.

Algunos ejemplos:

+-----------------------+------------------------------------------------+
| Expresión Proporciona | Explicación                                    |
|=======================|================================================|
| "mypkg"               | Proporciona "mypkg", utilizando la versión de  |
|                       | distribución                                   |
+-----------------------+------------------------------------------------+
| "mypkg (1.1)"         | Proporcione "mypkg" versión 1.1,               |
|                       | independientemente de la versión de            |
|                       | distribución                                   |
+-----------------------+------------------------------------------------+

Un paquete puede declarar que obsoleto otros paquetes utilizando el
argumento de palabra clave *obsoletes*. El valor para esto es similar
al de la palabra clave *requires*: una lista de cadenas que dan
especificadores de módulo o paquete. Cada especificador consta de un
nombre de módulo o paquete opcionalmente seguido de uno o más
calificadores de versión. Los calificadores de versión se dan entre
paréntesis después del nombre del módulo o paquete.

Las versiones identificadas por los calificadores son aquellas que
están obsoletas por la distribución que se describe. Si no se dan
calificadores, se entiende que todas las versiones del módulo o
paquete nombrado están obsoletas.


2.5. Instalar scripts
=====================

Hasta ahora hemos estado tratando con módulos Python puros y no puros,
que generalmente no se ejecutan solos sino que se importan mediante
scripts.

Los scripts son archivos que contienen el código fuente de Python,
destinados a iniciarse desde la línea de comandos. Los scripts no
requieren que Distutils haga nada muy complicado. La única
característica inteligente es que si la primera línea del script
comienza con "#!" Y contiene la palabra "python", Distutils ajustará
la primera línea para referirse a la ubicación actual del intérprete.
Por defecto, se reemplaza con la ubicación actual del intérprete. La
opción "-executable" (o "-e") permitirá que la ruta del intérprete se
anule explícitamente.

La opción "scripts" simplemente es una lista de archivos a manejar de
esta manera. Desde el script de configuración PyXML:

   setup(...,
         scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']
         )

Distinto en la versión 3.1: Todos los scripts también se agregarán al
archivo "MANIFEST" si no se proporciona una plantilla. Ver Especificar
los archivos a distribuir.


2.6. Instalar datos del paquete
===============================

A menudo, se necesitan instalar archivos adicionales en un paquete.
Estos archivos son a menudo datos que están estrechamente relacionados
con la implementación del paquete, o archivos de texto que contienen
documentación que podría ser de interés para los programadores que
usan el paquete. Estos archivos se llaman *paquetes de datos <package
data>*.

Los datos del paquete se pueden agregar a los paquetes utilizando el
argumento de palabra clave "package_data" para la función "setup()".
El valor debe ser una asignación del nombre del paquete a una lista de
nombres de ruta relativos que deben copiarse en el paquete. Las rutas
se interpretan como relativas al directorio que contiene el paquete
(la información de la asignación "package_dir" se usa si corresponde);
es decir, se espera que los archivos formen parte del paquete en los
directorios de origen. También pueden contener patrones glob.

Los nombres de ruta pueden contener porciones de directorio; cualquier
directorio necesario se creará en la instalación.

Por ejemplo, si un paquete debe contener un subdirectorio con varios
archivos de datos, los archivos se pueden organizar de esta manera en
el árbol de origen:

   setup.py
   src/
       mypkg/
           __init__.py
           module.py
           data/
               tables.dat
               spoons.dat
               forks.dat

La llamada correspondiente a "setup()" podría ser:

   setup(...,
         packages=['mypkg'],
         package_dir={'mypkg': 'src/mypkg'},
         package_data={'mypkg': ['data/*.dat']},
         )

Distinto en la versión 3.1: Todos los archivos que coincidan con
"package_data" se agregarán al archivo "MANIFEST" si no se proporciona
una plantilla. Ver Especificar los archivos a distribuir.


2.7. Instalar archivos adicionales
==================================

La opción "data_files" se puede usar para especificar archivos
adicionales necesarios para la distribución del módulo: archivos de
configuración, catálogos de mensajes, archivos de datos, cualquier
cosa que no se ajuste a las categorías anteriores.

"data_files" especifica una secuencia de pares (*directory*, *files*)
de la siguiente manera:

   setup(...,
         data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
                     ('config', ['cfg/data.cfg'])],
        )

Cada par (*directory*, *files*) en la secuencia especifica el
directorio de instalación y los archivos a instalar allí.

Cada nombre de archivo en *files* se interpreta en relación con el
script "setup.py" en la parte superior de la distribución de origen
del paquete. Tenga en cuenta que puede especificar el directorio donde
se instalarán los archivos de datos, pero no puede cambiar el nombre
de los archivos de datos.

El *directory* debe ser una ruta relativa. Se interpreta en relación
con el prefijo de instalación ("sys.prefix" de Python para
instalaciones del sistema; "site.USER_BASE" para instalaciones de
usuario). Distutils permite que *directory* sea una ruta de
instalación absoluta, pero esto se desaconseja ya que es incompatible
con el formato de empaquetado de la rueda. No se utiliza información
de directorio de *files* para determinar la ubicación final del
archivo instalado; solo se usa el nombre del archivo.

Puede especificar las opciones "data_files" como una secuencia simple
de archivos sin especificar un directorio de destino, pero esto no es
recomendable, y el comando **install** imprimirá una advertencia en
este caso. Para instalar archivos de datos directamente en el
directorio de destino, se debe dar una cadena vacía como directorio.

Distinto en la versión 3.1: Todos los archivos que coincidan con
"data_files" se agregarán al archivo "MANIFEST" si no se proporciona
una plantilla. Ver Especificar los archivos a distribuir.


2.8. Metadatos adicionales
==========================

El script de configuración puede incluir metadatos adicionales más
allá del nombre y la versión. Esta información incluye:

+------------------------+-----------------------------+-------------------+----------+
| Metadatos              | Descripción                 | Valor             | Notas    |
|========================|=============================|===================|==========|
| "name"                 | nombre del paquete          | cadena de         | (1)      |
|                        |                             | caracteres corta  |          |
+------------------------+-----------------------------+-------------------+----------+
| "version"              | versión de este lanzamiento | cadena de         | (1)(2)   |
|                        |                             | caracteres corta  |          |
+------------------------+-----------------------------+-------------------+----------+
| "author"               | nombre del autor del        | cadena de         | (3)      |
|                        | paquete                     | caracteres corta  |          |
+------------------------+-----------------------------+-------------------+----------+
| "author_email"         | dirección de correo         | dirección de      | (3)      |
|                        | electrónico del autor del   | correo            |          |
|                        | paquete                     | electrónico       |          |
+------------------------+-----------------------------+-------------------+----------+
| "maintainer"           | nombre del responsable del  | cadena de         | (3)      |
|                        | paquete                     | caracteres corta  |          |
+------------------------+-----------------------------+-------------------+----------+
| "maintainer_email"     | dirección de correo         | dirección de      | (3)      |
|                        | electrónico del mantenedor  | correo            |          |
|                        | del paquete                 | electrónico       |          |
+------------------------+-----------------------------+-------------------+----------+
| "url"                  | página de inicio del        | URL               | (1)      |
|                        | paquete                     |                   |          |
+------------------------+-----------------------------+-------------------+----------+
| "description"          | descripción breve y         | cadena de         |          |
|                        | resumida del paquete        | caracteres corta  |          |
+------------------------+-----------------------------+-------------------+----------+
| "long_description"     | descripción más larga del   | cadena de         | (4)      |
|                        | paquete                     | caracteres larga  |          |
+------------------------+-----------------------------+-------------------+----------+
| "download_url"         | ubicación donde se puede    | URL               |          |
|                        | descargar el paquete        |                   |          |
+------------------------+-----------------------------+-------------------+----------+
| "classifiers"          | una lista de clasificadores | lista de cadenas  | (6)(7)   |
|                        |                             | de caracteres     |          |
+------------------------+-----------------------------+-------------------+----------+
| "platforms"            | una lista de plataformas    | lista de cadenas  | (6)(8)   |
|                        |                             | de caracteres     |          |
+------------------------+-----------------------------+-------------------+----------+
| "keywords"             | una lista de palabras clave | lista de cadenas  | (6)(8)   |
|                        |                             | de caracteres     |          |
+------------------------+-----------------------------+-------------------+----------+
| "license"              | licencia para el paquete    | cadena de         | (5)      |
|                        |                             | caracteres corta  |          |
+------------------------+-----------------------------+-------------------+----------+

Notas:

1. Estos campos son obligatorios.

2. Se recomienda que las versiones tomen la forma
   *major.minor[.patch[.sub]]*.

3. Se debe identificar al autor o al mantenedor. Si se proporciona el
   mantenedor, distutils lo enumera como el autor en "PKG-INFO".

4. PyPI utiliza el campo "long_description" cuando publica un paquete
   para construir su página de proyecto.

5. El campo "license" es un texto que indica la licencia que cubre el
   paquete donde la licencia no es una selección de los clasificadores
   de Trove *"License"*. Vea el campo "Classifier". Tenga en cuenta
   que hay una opción de distribución de "license" que está en desuso
   pero que aún actúa como un alias para la "license".

6. Este campo debe ser una lista.

7. Los clasificadores válidos se enumeran en PyPI.

8. Para preservar la compatibilidad con versiones anteriores, este
   campo también acepta una cadena. Si pasa una cadena separada por
   comas "'foo, bar'", se convertirá en "['foo', 'bar']", de lo
   contrario, se convertirá en una lista de una cadena de caracteres.

'cadenas de caracteres cortas'
   Una sola línea de texto, no más de 200 caracteres.

'cadenas de caracteres largas'
   Multiple lines of plain text in reStructuredText format (see
   https://docutils.sourceforge.io/).

'lista de cadenas de caracteres'
   Vea abajo.

Codificar la información de la versión es un arte en sí mismo. Los
paquetes de Python generalmente se adhieren al formato de versión
*major.minor[.patch][sub]*. El número principal es 0 para las
versiones iniciales y experimentales de software. Se incrementa para
versiones que representan hitos importantes en un paquete. El número
menor se incrementa cuando se agregan nuevas características
importantes al paquete. El número de parche aumenta cuando se realizan
versiones de corrección de errores. La información adicional de la
versión final a veces se usa para indicar sublanzamientos. Estos son
"a1, a2, ..., aN" (para versiones alfa, donde la funcionalidad y la
API pueden cambiar), "b1, b2, ..., bN" (para versiones beta, que solo
corrigen errores) y "pr1 , pr2, ..., prN" (para la prueba final de
lanzamiento previo al lanzamiento). Algunos ejemplos:

0.1.0
   el primer lanzamiento experimental de un paquete

1.0.1a2
   la segunda versión alfa de la primera versión del parche 1.0

"classifiers" debe ser especificado en una lista:

   setup(...,
         classifiers=[
             'Development Status :: 4 - Beta',
             'Environment :: Console',
             'Environment :: Web Environment',
             'Intended Audience :: End Users/Desktop',
             'Intended Audience :: Developers',
             'Intended Audience :: System Administrators',
             'License :: OSI Approved :: Python Software Foundation License',
             'Operating System :: MacOS :: MacOS X',
             'Operating System :: Microsoft :: Windows',
             'Operating System :: POSIX',
             'Programming Language :: Python',
             'Topic :: Communications :: Email',
             'Topic :: Office/Business',
             'Topic :: Software Development :: Bug Tracking',
             ],
         )

Distinto en la versión 3.7: "setup" ahora advierte cuando los campos
"classifiers", "keywords" o "platforms" no se especifican como una
lista o una cadena de caracteres.


2.9. Depuración del script de configuración
===========================================

A veces las cosas salen mal y el script de configuración no hace lo
que el desarrollador quiere.

Distutils detecta cualquier excepción al ejecutar el script de
configuración e imprime un mensaje de error simple antes de que
finalice el script. La motivación para este comportamiento es no
confundir a los administradores que no saben mucho acerca de Python y
están tratando de instalar un paquete. Si obtienen un gran rastreo
desde las profundidades de Distutils, pueden pensar que el paquete o
la instalación de Python están rotos porque no leen hasta el final y
ven que es un problema de permiso.

Por otro lado, esto no ayuda al desarrollador a encontrar la causa de
la falla. Para este propósito, la variable de entorno
"DISTUTILS_DEBUG" se puede establecer en cualquier cosa excepto una
cadena vacía, y distutils ahora imprimirá información detallada sobre
lo que está haciendo, volcará el rastreo completo cuando ocurra una
excepción e imprimirá todo el comando línea cuando falla un programa
externo (como un compilador de C).
