Python Para Todos Ii

  • Uploaded by: Mauro Miguel Melo
  • 0
  • 0
  • December 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Python Para Todos Ii as PDF for free.

More details

  • Words: 9,289
  • Pages: 19
Distribución de módulos Python Greg Ward 8 de diciembre de 2000 E-mail: [email protected] Resumen Este documento describe las Herramientas de Distribución de Python (“Distutils”) desde el punto de vista del desarrollador de módulos. Describe cómo utilizar las Distutils para hacer que los módulos y extensiones de Python fácilmente accesibles a una amplia audiencia haciendo más automático el proceso de compilar/liberar/instalar.

Índice General 1

Introducción

2

2

Conceptos y terminología 2.1 Un ejemplo simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Terminología general de Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Terminología específica de Distutils . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 3 4 5

3

Escritura del guion de instalación 3.1 Enumeración de paquetes completos . . . 3.2 Enumeración de módulos individuales . . 3.3 Descripción de los módulos de extensión . Nombre de extensiones y de paquetes . . Ficheros fuente de extensión . . . . . . . Opciones del preprocesador . . . . . . . . Opciones de bibliotecas . . . . . . . . . .

5 6 6 7 7 8 8 9

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

4

Escritura del fichero de configuración de la instalación

10

5

Creación de una distribución de fuentes 5.1 Especificación de los ficheros a distribuir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 Opciones relativas al manifiesto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

12 12 14

6

Creación de distribuciones binarias 6.1 Creación de distribuciones compiladas bobas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Creación de paquetes RPM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 Creación de instaladores de Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14 16 16 18

7

Ejemplos 7.1 Distribución Python pura (por módulo) . 7.2 Distribución Python pura (por paquete) 7.3 Módulo de extensión simple . . . . . . 7.4 Módulos de extensión múltiples . . . . 7.5 Todo junto . . . . . . . . . . . . . . . .

18 18 18 18 18 18

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

8

Extensión de las Distutils 8.1 Extensión de órdenes existentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2 Implementación de nuevas órdenes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18 18 18

9

Referencia 9.1 Compilación de módulos: la familia de órdenes build . . . . . . . . build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . build_py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . build_ext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . build_clib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2 Instalación de módulos: la familia de órdenes install . . . . . . . install_lib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . install_data . . . . . . . . . . . . . . . . . . . . . . . . . . . . install_scripts . . . . . . . . . . . . . . . . . . . . . . . . . 9.3 Acciones de limpieza: la orden clean . . . . . . . . . . . . . . . . . 9.4 Creación de una distribución de fuentes: la orden sdist . . . . . . . 9.5 Creación de una distribución compilada: la familia de órdenes bdist blib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . blib_dumb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . blib_rpm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . blib_wise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18 18 18 18 18 18 18 18 18 18 19 19 19 19 19 19 19

1

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

Introducción

Hasta ahora, los desarrolladores de módulos de Python no disponían de mucha infraestructura para la distribución de módulos, ni los usuarios de Python de soporte para instalar y mantener módulos de terceras partes. Con la introducción de las Herramientas de Distribución de Python (“Distutils” para abreviar) en Python 1.6, esta situación empezará a mejorar. Este documento sólo cubre el uso de Distutils para distribuir tus módulos de Python. El uso de Distutils no te ata a Python 1.6 o superiores, sin embargo. Las Distutils funcionan perfectamente con Python 1.5.2 y es razonable (se espera que común) que los usuarios de Python descarguen e instalen por separado las Distutils para poder instalar tus módulos. Los usuarios de Python 1.6 (o superiores), por supuesto, no tendrán que añadir nada a su distribución de Python para usar las Distutils en la instalación de módulos de terceros. Este documento se concentra en el papel del desarrollador/distribuidor. Si buscas información sobre la instalación de módulos de Python, deberías consultar el manual Instalación de módulos de Python.

2

Conceptos y terminología

El uso de las Distutils es bastante simple, tanto para los desarrolladores de módulos como para los usuarios/administradores que han de instalar módulos de terceros. Como desarrollador, tus responsabilidades (¡además de escribir código fiable, bien documentado y probado, por supuesto!) son: • escribir un guion de instalación (‘setup.py’ por convención) • (opcional) escribir un fichero de configuración de la instalación • crear una distribución de código fuente • (opcional) crear una o más distribuciones compiladas (binarias) 2

2

Conceptos y terminología

En este documento está cubierta cada una de estas tareas. No todos los desarrolladores de módulos tienen acceso a varias plataformas, por lo que no siempre es factible esperar que creen varias distribuciones binarias. Se espera que aparecerán intermediarios (los empaquetadores) para cubrir esta necesidad. Los empaquetadores tomarán las distribuciones de código fuente liberadas por los desarrolladores de módulos, las compilarán en una o varias plataformas y liberarán las distribuciones binarias resultantes. De este modo, los usuarios de las plataformas más comunes serán capaces de instalar las distribuciones de módulos de Python más extendidas del modo más natural en su plataforma, sin tener que ejecutar un solo guion ni compilar una línea de código.

2.1

Un ejemplo simple

El guion de instalación suele ser bastante simple, aunque, por estar escrito en Python, no hay límites arbitrarios sobre lo que se puede hacer con él.1 Si sólo quieres distribuir un módulo denominado foo, contenido en un fichero ‘foo.py’, tu guion de instalación puede reducirse a esto: from distutils.core import setup setup (name = "foo", version = "1.0", py_modules = ["foo"])

Observaciones: • la mayoría de la información que se proporciona a las Distutils va en forma de argumentos clave a la función setup() • dichos argumentos pertenecen a dos categorías: meta-datos del paquete (nombre, número de versión) e información sobre lo contenido en el paquete (una lista de módulos en Python puro, en este caso) • los módulos se especifican por nombre de módulo, no nombre de fichero (esto se aplica también a los paquetes y extensiones) • se recomienda que proporciones más meta-datos, en particular tu nombre, dirección electrónica de correo y un URL del proyecto (consulta la sección 3 si quieres ver un ejemplo) Para crear una distribución de código fuente para este módulo, crearías un guion de instalación, ‘setup.py’, que contuviera el código anterior, y lo ejecutarías: python setup.py sdist

lo que crearía un fichero comprimido (por ejemplo, un fichero tar de Unix, un zip en Windows) que contendría tu guion de instalación, ‘setup.py’ y tu módulo, ‘foo.py’. El fichero se llamaría ‘Foo-1.0.tar.gz’ (o ‘.zip’) y se desempaquetaría en un directorio ‘Foo-1.0’. Si un usuario/a desea instalar tu módulo foo module, sólo tiene que descargar ‘Foo-1.0.tar.gz’ (o ‘.zip’), desempaquetarlo y, desde el directorio ‘Foo-1.0’, ejecutar python setup.py install

lo que finalmente copiaría ‘foo.py’ al directorio adecuado para módulos de terceros en su instalación de Python. Este sencillo ejemplo muestra algunos conceptos fundamentales de las Distutils: Primero, tanto los desarrolladores como los instaladores tienen la misma interfaz de usuario básica, el guion de instalación. La diferencia radica en qué 1 Pero modérate respecto a poner operaciones arbitrariamente costosas en el guion de instalación. Al contrario de los guiones del tipo de autoconf [N. del T.: autoconf es la herramienta de GNU de configuración multiplataforma], es posible que el guion de instalación se ejecute varias veces en el curso de la compilación e instalación de la distribución del módulo. Si es necesario que incluyas pasos potencialmente costosos en proceso dentro de la cadena de Distutils, consulta la sección 8 sobre la extensión de las Distutils.

2.1 Un ejemplo simple

3

órdenes de Distutils utilizan: la orden sdist es utilizada casi exclusivamente por desarrolladores de módulos, mientras que la orden install es más común para los instaladores (aunque la mayoría de los desarrolladores querrán instalar su propio código ocasionalmente). Si deseas ponerles las cosas realmente fáciles a tus usuarios, puedes crear una o más distribuciones compiladas para ellos. Por ejemplo, si estás funcionando en una máquina Windows y quieres facilitarles las cosas a otros usuarios de Windows, puedes crear un instalador ejecutable (el tipo de distribución compilada más adecuado para esta plataforma) con la orden bdist_wininst. Por ejemplo: python setup.py bdist_wininst

creará un instalador ejecutable, ‘Foo-1.0.win32.exe’, en el directorio actual. **no implementado aún** (Otro modo de crear instaladores ejecutables para Windows es con la orden bdist_wise, que hace uso de Wise, el generador de instaladores que se utiliza en el propio Python, para generar el instalador. Los instaladores basados en Wise son más adecuados para aplicaciones de peso, que necesitan las funciones de un instalador “de verdad”. bdist_wininst crea un fichero zip autoextraíble con una interfaz de usuario mínima, suficiente para colecciones de módulos pequeñas y medianas. Necesitarás tener instalada la versión XXX de Wise en tu sistema para que la orden bdist_wise funcione. Está disponible en http://foo/bar/baz.) En la actualidad (Distutils 0.9.2), el único formato de distribución compilado es el RPM, implementado por la orden bdist_rpm. Por ejemplo, la siguiente orden creará un fichero RPM llamado ‘Foo-1.0.noarch.rpm’: python setup.py bdist_rpm

(utiliza la orden rpm, por lo que ha de ser ejecutado en un sistema basado en RPM, como Red Hat Linux, SuSE Linux o Mandrake Linux). Se puede consultar qué formatos de distribución están disponibles en cualquier momento ejecutando python setup.py bdist --help-formats

2.2 Terminología general de Python Si estás leyendo este documento, es probable que tengas una idea clara de lo que son los módulos, extensiones, etc. De cualquier manera, para estar seguro de que todos hablamos de lo mismo, damos el siguiente glosario de términos comunes de Python: módulo la unidad básica de reutilizabilidad de código en Python: un bloque de código importado por otro código. Consideramos tres tipos de módulo: módulos Python puros, módulos de extensión y paquetes. módulos Python puros escritos en Python y contenidos en un solo fichero ‘.py’ (y sus posibles ‘.pyc’ ‘.pyo’ files asociados). Denominado a veces “módulo puro”. módulo de extensión un módulo escrito en el lenguaje de bajo nivel de la implementación concreta: C/C++ en el caso de CPython, Java en el de JPython. Contenido típicamente en un único fichero precompilado de carga dinámica, es decir, un fichero objeto compartido (‘.so’) en Unix/CPython, una DLL (con la extensión cambiada a ‘.pyd’) en el caso de Windows/CPython o un fichero de clase Java (‘.class’) en el caso de JPython (en la actualidad, las Distutils solo gestionan extensiones en C/C++ para CPython). paquete un módulo que contiene otros módulos. Suele estar contenido en un subdirectorio del sistema de ficheros y se destaca por tener un fichero de nombre ‘__init__.py’. paquete raíz la raíz de la jerarquía de paquetes. No es realmente un paquete, porque no tiene un fichero ‘__init__.py’, pero había que bautizarlo. La inmensa mayoría de la biblioteca estándar reside en el paquete raíz. También residen ahí muchos módulos pequeños de terceros que no pertenecen a una biblioteca mayor. Al contrario que 4

2

Conceptos y terminología

los paquetes normales, los módulos del paquete raíz pueden hallarse en muchos directorios, de hecho cada directorio de sys.path puede contribuir módulos al paquete raíz..

2.3

Terminología específica de Distutils

Los siguientes términos son específicos de la distribución de módulos de Python mediante Distutils: distribución de módulos una colección de módulos de Python distribuida conjuntamente como un recurso descargable y dirigida a ser instalada solidariamente. Como ejemplos de distribuciones de módulos ampliamente conocidas se puede mencionar Numeric Python, PyXML, PIL (la Biblioteca de gestión de imágenes de Python) o mxDateTime (se debería llamar a esto paquete, pero el término ya era utilizado en el contexto de Python y una distribución de módulos puede tener cero, uno o varios paquetes Python. distribución de módulos pura una distribución de módulos que sólo contiene módulos Python y paquete puros. A veces se denomina “distribución pura”. distribución de módulos no pura una distribución de módulos que contiene al menos un módulo de extensión. A veces se denomina “distribución no pura”. raíz de la distribución el directorio de nivel más alto de los ficheros de la distribución. Es el directorio en el que reside ‘setup.py’ y desde el que hay que ejecutarlo.

3

Escritura del guion de instalación

El guion de instalación es el centro de toda la actividad de la compilación, distribución e instalación de módulos mediante las Distutils. El propósito principal del guion de instalación es el de describir la distribución de tu módulo a las Distutils, para que las diversas órdenes que operan sobre tus módulos realicen el trabajo deseado. Según vimos en la sección 2.1, el guion de instalación consta principalmente de una llamada a setup() y la mayoría de la información proporcionada a las Distutils por el desarrollador del módulo se proporciona como argumentos clave a setup(). He aquí un ejemplo ligeramente más evolucionado, que seguiremos en las siguientes secciones: el propio guion de instalación de las Distutils (recuerda que aunque las Distutils vienen incluidas en Python 1.6 y posteriores, existen de manera independiente para que los usuarios de Python 1.5.2 puedan utilizarlas para instalar otras distribuciones de módulos. El guion de instalación de las propias Distutils, que se muestra aquí, se utiliza para 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 = "[email protected]", url = "http://www.python.org/sigs/distutils-sig/", packages = [’distutils’, ’distutils.command’], )

Hay sólo dos diferencias entre este guion y el guion trivial para la distribución de un fichero presentado en la sección 2.1: más meta-datos y la especificación de módulos de Python puros por paquete, en lugar de por módulo. Esto es relevante, ya que las Distutils poseen más de veinte módulos divididos en (hasta ahora) dos paquetes. Sería tedioso, y difícil de mantener, generar una lista de módulos detallada. 2.3 Terminología específica de Distutils

5

Observa que los nombres del sistema de archivos (ficheros y directorios) del guion debe escribirse mediante la convención de Unix, es decir, separada por barras ‘/’. Las Distutils se ocuparán de convertir esta representación independiente de la plataforma en la que sea apropiada para la plataforma de destino antes de usarla. Esto hace que tu guion de instalación sea transportable entre diferentes sistemas operativos, lo que es, por supuesto, una de las metas más importantes de las Distutils. Siguiendo este objetivo, todos los nombres de subdirectorios se separan por barras (los programadores de MacOS deberían tener en cuenta que la ausencia de barra inicial indica un camino relativo, la convención opuesta a la usual en Mac, relativa a los dos puntos).

3.1

Enumeración de paquetes completos

La opción packages indica a las Distutils que procese (compile, distribuya, instale, etc.) todos los módulos en Python puros hallados en cada paquete mencionado en la lista packages. Para hacerlo, por supuesto, debe existir una correspondencia entre los nombres de los paquetes y los directorios del sistema de ficheros. La correspondencia por defecto es la evidente, es decir, el paquete distutils se encuentra en el directorio ‘distutils’ relativo a la raíz de la distribución. De este modo, al decir packages = [’foo’] en tu guion de instalación, te comprometes a que las Distutils encuentren un fichero ‘foo/__init__.py’ (posiblemente con diferente sintaxis en tu sistema, pero te la puedes imaginar) relativo al directorio en el que reside tu guion de instalación (si no cumples tu compromiso, las Distutils emitirán un aviso pero procesarán el paquete incorrecto de todos modos). Si utilizas una convención diferente para ordenar tu directorio de fuentes, no hay problema: Sólo tienes que proporcionar la opción package_dir para indicar a las Distutils tu convención. Por ejemplo, si mantienes todo el código fuente en Python bajo ‘lib’, para que los módulos del “paquete raíz” (los que no están en ningún paquete) estén directamente en ‘lib’, los módulos del paquete foo estén en ‘lib/foo’, y así sucesivamente, pondrías: package_dir = {’’: ’lib’}

en tu guion de instalación (las claves de este diccionario son nombres de paquetes y un nombre vacío de paquete indica el paquete raíz). En tal caso, cuando digas packages = [’foo’], quieres decir que existe el fichero ‘lib/foo/__init__.py’. Otra convención posible es poner el paquete foo justo en ‘lib’, el paquete foo.bar en ‘lib/bar’, etc. Esto se describiría en el guion de instalación así: package_dir = {’foo’: ’lib’}

Una entrada package: dir en el diccionario package_dir se aplica implícitamente a todos los paquetes bajo package, por lo que el caso de foo.bar se gestiona de modo automáticamente. En este ejemplo, tener packages = [´ foo’, ´ foo.bar’] indica a las Distutils que busque ‘lib/__init__.py’ y ‘lib/bar/__init__.py’ (no olvides que, aunque package_dir se aplica recursivamente, se debe enumerar de manera explícita todos los paquetes de packages: las Distutils no recorrerán tu árbol de directorios buscando un fichero ‘__init__.py’).

3.2

Enumeración de módulos individuales

Para una distribución de módulos pequeña, puede que prefieras enumerar todos los módulos, en lugar de enumerar paquetes (especialmente en el caso de un solo módulo que va en el “paquete raíz”). Este caso trivial se presentó en la sección 2.1. He aquí un ejemplo más sustancioso: py_modules = [’mod1’, ’pkg.mod2’]

Se describen dos módulos, uno de ellos en el “paquete raíz” y el otro en el paquete pkg. De nuevo, la disposición por omisión de paquetes y directorios implica que se pueden encontrar estos dos módulos en ‘mod1.py’ y ‘pkg/mod2.py’, y 6

3

Escritura del guion de instalación

que también existe ‘pkg/__init__.py’. Y de nuevo, puedes forzar la correspondencia entre paquetes y directorios usando la opción package_dir.

3.3

Descripción de los módulos de extensión

Igual que escribir módulos de extensión de Python es algo más complicado que escribir simples módulos de Python, describírselos a las Distutils también resulta más complicado. A diferencia de los módulos puros, no basta con enumerar los paquetes y los módulos y esperar que las Distutils salgan y encuentren los ficheros adecuados. Hay que especificar el nombre de la extensión, los ficheros fuente y los requisitos de compilación/enlace que pudiera haber (directorios de “include”, bibliotecas de enlace. . . ). Todo esto se hace mediante otro argumento clave a setup(), la opción extensions. extensions es simplemente una lista de instancias de Extension, cada una de las cuales describe un módulo de extensión simple. Supón que tu distribución incluye una sola extensión, llamada foo e implementada por ‘foo.c’. Si no se necesitan instrucciones adicionales para el compilador/enlazador, es bastante simple describir esta extensión: Extension("foo", ["foo.c"])

La clase Extension se puede importar de distutils.core, junto con setup(). Así, el guion de configuración de una distribución de módulos que contiene sólo esta extensión y nada más, sería: 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 subyacente de construcción de extensiones implementada por la orden built_ext) proporciona mucha flexibilidad a la hora de describir extensiones de Python, tal como se describe en las secciones posteriores. Nombre de extensiones y de paquetes El primer argumento del constructor de Extension siempre es el nombre de la extensión, nombres de paquetes incluidos. Por ejemplo, Extension("foo", ["src/foo1.c", "src/foo2.c"])

describe una extensión que reside en el paquete raíz, mientras Extension("pkg.foo", ["src/foo1.c", "src/foo2.c"])

describe la misma extensión del paquete pkg. Los archivos fuente y el código objeto resultante son idénticos en ambos casos. La única diferencia es dónde reside la extensión resultante (y, consecuentemente, su lugar dentro de la jerarquía de espacios nominales de Python). Si hay varias extensiones dentro del mismo paquete (o dentro del mismo paquete base), se debe usar el argumento clave ext_package al llamar a la función setup(). Por ejemplo,

3.3 Descripción de los módulos de extensión

7

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. Ficheros fuente de extensión El segundo argumento del constructor de Extension es una lista de ficheros fuente. Como las Distutils sólo dan soporte a extensiones en C/C++, suelen ser ficheros fuente C/C++. Asegúrate de usar las extensiones apropiadas para distinguir los ficheros en C++: Parece que ‘.cc’ y ‘.cpp’ funcionan tanto en Unix como en Windows. Sin embargo, también se puede incluir en la lista ficheros de interfaz SWIG (‘.i’). La orden build_ext gestiona extensiones SWIG: Ejecutará SWIG sobre el fichero de interfaz y compilará el fichero C/C++ a la extensión. **SWIG support is rough around edges and largely untested; especially SWIG support of C++ extensions! Explain in more detail here when the interface firms up.** Sobre algunas plataformas, es posible incluir ficheros no-fuente para que los procese el compilador y los incluya en la extensión. En la actualidad, esto se aplica a los ficheros de recursos de Windows para Visual C++. **get more detail on this feature from Thomas Heller!** Opciones del preprocesador Hay tres argumentos opcionales de Extension que resultarán prácticos si hay que incluir directorios de búsqueda o macros del preprocesador para definir/indefinir: include_dirs, define_macros y undef_macros. Por ejemplo, si la extensión necesita ficheros de cabecera en el directorio ‘include’ de la raíz de la instalación, usa la opción include_dirs: Extension("foo", ["foo.c"], include_dirs=["include"])

Es posible especificar directorios absolutos. Si te consta que la extensión sólo se va a compilar en sistemas Unix con X11R6 instalado en ‘/usr’, vale con poner Extension("foo", ["foo.c"], include_dirs=["/usr/include/X11"])

Se debe evitar este tipo de uso no-portable si esperar distribuir el código. Sería mejor incluir (p. ej.) <X11/Xlib.h>. Si hay que incluir cabeceras de otra extensión de Python, puedes aprovecharte de que las Distutils instalan las cabeceras de Python de manera consistente. Por ejemplo, las cabeceras de Numerical Python están instaladas (en una instalación estándar de Unix) en ‘/usr/local/include/python1.5/Numerical’ (la ubicación exacta dependerá de la plataforma y de la instalación de Python). Como el directorio de cabeceras C de Python —‘/usr/local/include/python1.5’ en este caso— siempre está incluido en el camino de búsqueda al compilar extensiones de Python, lo mejor es incluir (para este ejemplo) . Si te empeñas en poner el directorio ‘Numerical’ en tu camino de búsqueda de cabeceras, puedes encontrar el directorio usando el módulo sysconfig de las Distutils:

8

3

Escritura del guion de instalación

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 resulte bastante portable (funcionará en cualquier instalación de de Python, independientemente de la plataforma) es probable que resulte más sencillo escribir el código C de una manera más coherente. Se pueden definir e indefinir macros del 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 para definir (una cadena) y value es su valor: una cadena o None. Definir una macro FOO a None equivale a una línea #define FOO el el fuente C. La mayoría de los compiladores pondrán FOO al valor cadena 1.) undef_macros es una lista de macros a indefinir. Por ejemplo: Extension(..., define_macros=[(’NDEBUG’, ’1’)], (’HAVE_STRFTIME’, None), undef_macros=[’HAVE_FOO’, ’HAVE_BAR’])

equivale a poner esto al principio de cada fichero fuente C: #define NDEBUG 1 #define HAVE_STRFTIME #undef HAVE_FOO #undef HAVE_BAR

Opciones de bibliotecas También se pueden especificar las bibliotecas de enlace y los directorios en los que buscar dichas bibliotecas. La opción libraries es una lista de bibliotecas de enlace, library_dirs es una lista de directorios en los que buscar bibliotecas en el momento de enlazar y runtime_library_dirs es una lista de directorios en los que buscar bibliotecas compartidas (DLLs, en Windows) en tiempo de ejecución. Por ejemplo, si hay que enlazar bibliotecas que se sabe que están en el camino de búsqueda de bibliotecas estándar en los sistemas de destino: Extension(..., libraries=["gdbm", "readline"])

Si es necesario enlazar con bibliotecas de una ubicación no estándar, habrá que incluir la ubicación en library_dirs: Extension(..., library_dirs=["/usr/X11R6/lib"], libraries=["X11", "Xt"])

Como se ha indicado, se debe evitar este tipo de construcción no portable si tienes intención de distribuir código.

3.3 Descripción de los módulos de extensión

9

**still undocumented: extra_objects, extra_compile_args, extra_link_args, export_symbols—none of which are frequently needed, some of which might be completely unnecessary!**

4

Escritura del fichero de configuración de la instalación

A menudo, no es posible escribir cada cosa necesaria para construir una distribución a priori: puede que necesites obtener información del usuario o de su sistema para proseguir. Siempre que tal información sea simple (una lista de directorios en los que buscar cabeceras o bibliotecas de C, por ejemplo) resulta sencillo proporcionar un fichero de configuración, ‘setup.cfg’, y dejar que lo edite el usuario. Los ficheros de configuración también permiten proporcionar valores por omisión de cualquier opción de línea de órdenes que el usuario puede forzar mediante opciones en la línea de órdenes o mediante la edición de dichos ficheros.. Si las necesidades son más avanzadas, como, por ejemplo, determinar qué extensiones se han de construir dependiendo de las propiedades de la instalación del sistema, se necesita usar los servicios de “auto-configuración” de las Distutils. Empezaron a aparecer en la versión 0.9, pero, en el momento en que se escribe esto, no son suficientemente estables o maduras para su uso en entornos de producción. **should reference description of distutils config files in “Installing” manual here** El fichero de configuración de la instalación es un término medio entre el guion de instalación (que idealmente es transparente para el instalador2 ) y la línea de órdenes del guion de instalación, que queda totalmente fuera de tu control y al albedrío del instalador. De hecho, ‘setup.cfg’ (y otros ficheros de configuración de Distutils presentes en el sistema final) se procesan tras el contenido del guion de instalación, pero antes de la línea de órdenes. Esto supone varias consecuencias favorables: • los instaladores pueden forzar cosas que pongas en ‘setup.py’ editando ‘setup.cfg’ • Puedes proporcionar valores por omisión no estándar para las opciones que no sean fáciles de incluir en ‘setup.py’ • los instaladores pueden forzar cualquier cosa de ‘setup.cfg’ usando las opciones de línea de órdenes de ‘setup.py’ La sintaxis básica del fichero de configuración es simple: [orden] opción=valor ...

donde orden es una de las órdenes de Distutils (por ejemplo, build_py o install) y opción es una de las opciones válidas para dicha orden. En el fichero se puede proporcionar cualquier número de opciones para cada orden y se puede incluir cualquier número de secciones de orden. Se pasan por alto las líneas en blanco y los comentarios (desde el carácter # hasta el fin de la línea). Se puede dividir los valores de opciones largos sangrando las líneas posteriores a la primera. Se puede obtener la lista de opciones válidas para una orden particular con la opción universal --help (ayuda), por ejemplo: 2 Este

10

ideal no se logrará, probablemente, hasta que las Distutils den servicio de auto-configuración completo.

4

Escritura del fichero de configuración de la instalación

> python setup.py --help build_ext [...] Options for ’build_ext’ command: --build-lib (-b) directory for compiled extension modules --build-temp (-t) directory for temporary files (build by-products) --inplace (-i) ignore build-lib and put compiled extensions into the source directory alongside your pure Python modules --include-dirs (-I) list of directories to search for header files --define (-D) C preprocessor macros to define --undef (-U) C preprocessor macros to undefine [...]

o consultando la sección 9 de este documento (la referencia de órdenes). Observa que una opción que se escriba --pis-pas en la línea de órdenes se escribe pis_pas en los ficheros de configuración. Supón, por ejemplo, que quieres que las extensiones se compilen “en el sitio”: Hay una extensión pkg.ext y quieres que el fichero de la extensión compilada, ‘ext.so’ en Unix, se genere en el mismo directorio de fuentes que los módulos de Python puro pkg.mod1 y pkg.mod2. Siempre puedes usar la opción --inplace de la línea de órdenes para asegurarlo: python setup.py build_ext --inplace

Pero esto exige que se especifique siempre la orden build_ext y recordar proporcionar --inplace. Es más sencillo “ajustar y olvidar” esta opción incluyéndola en ‘setup.cfg’, el fichero de configuración de esta distribución: [build_ext] inplace=1

Esto afectará a todas las compilaciones de esta distribución de módulos, tanto si especificas build_ext como si no. Si incluyes ‘setup.cfg’ en la distribución de fuentes, también afectará a las compilaciones del usuario final, lo que puede no resultar adecuado para esta opción, ya que compilar siempre “en el sitio” las extensiones dañaría la instalación de distribución de módulos. En ciertos casos concretos, sin embargo, se construyen en su mismo directorio de instalación, así que es una posibilidad que puede resultar útil (distribuir extensiones que se han de compilar en el directorio de instalación casi siempre es inconveniente, sin embargo). Otro ejemplo: ciertas órdenes requieren muchas opciones que no cambian de una ejecución a la siguiente, por ejemplo, bdist_rpm requiere todo lo necesario para generar un fichero ‘spec’ para generar una distribución RPM. Parte de esta información viene del guion de instalación y parte es generada automáticamente por las Distutils (la lista de ficheros instalados, por ejemplo). Sin embargo, otra parte debe ser proporcionada en forma de opciones de bdist_rpm, tediosas de repetir en la línea de órdenes para cada ejecución. Por ello, he aquí un fragmento del propio ‘setup.cfg’ de las Distutils: [bdist_rpm] release = 1 packager = Greg Ward doc_files = CHANGES.txt README.txt USAGE.txt doc/ examples/

Observa que la opción doc_files es simplemente una ristra de cadenas separadas por blancos, dividida en múltiples líneas para favorecer la legibilidad.

11

5

Creación de una distribución de fuentes

Como se muestra en la sección 2.1, se usa la orden sdist para crear una distribución de fuentes. En el caso más sencillo, python setup.py sdist

(suponiendo que no se ha especificado ninguna de las opciones sdist el en guion de configuración o en el fichero de configuración), sdist genera el archivo comprimido con el formato más usual de la plataforma en cuestión. El formato por omisión es concatenado con tar y comprimido con gzip (‘.tar.gz’) en Unix y fichero ZIP en Windows. **no Mac OS support here** > Es posible especificar cuantos formatos sean necesarios usando la opción --formats, por ejemplo: python setup.py sdist --formats=gztar,zip

para generar un ‘.tar.gz’ y un ‘.zip’. Están disponibles los siguientes formatos: Formato zip gztar bztar ztar tar

Descripción fichero zip (‘.zip’) fichero tar/gzip (‘.tar.gz’) fichero tar/bzip2 (‘.tar.gz’) fichero tar comprimido (‘.tar.Z’) tar file (‘.tar’)

Notas (1),(3) (2),(4) (4) (4) (4)

Notas: (1) predeterminado en Windows (2) predeterminado en Unix (3) requiere utilidad zip externa o modulo zipfile (no incluido en la biblioteca estándar de Python) (4) requiere utilidades externas: tar y otra, como gzip, bzip2 o compress

5.1 Especificación de los ficheros a distribuir Si no se proporciona una lista explícita de ficheros (o instrucciones de cómo generarla), la orden sdist incluye un conjunto mínimo en la distribución de fuentes: • todos los ficheros fuentes Python implicados por py_modules y opciones packages • todos los ficheros fuente C mencionados en ext_modules u opciones libraries (**getting C library sources currently broken – no get_source_files() method in build_clib.py!**) • cualquier cosa con pinta de guion de pruebas: ‘test/test*.py’ (en la actualidad, las Distutils no hacen nada con los guiones de pruebas salvo incluirlos en las distribuciones de fuentes, pero en el futuro existirá una norma para la comprobación de las distribuciones de módulos de Python) • ‘README.txt’, léame, (o ‘README’), ‘setup.py’ (o como llamases a tu guion de configuración) y ‘setup.cfg’ Esto puede valer en algunos casos, pero es común que haya que especificar más ficheros para distribuir. El modo típico de hacerlo es escribir una plantilla del manifiesto, denominada ‘MANIFEST.in’ de forma predeterminada. La plantilla del manifiesto tiene simplemente una lista de instrucciones de cómo generar el fichero de manifiesto, denominado 12

5

Creación de una distribución de fuentes

‘MANIFEST’, que contiene la lista exacta de los ficheros a incluir en la distribución fuente. La orden sdist procesa esta plantilla y genera un manifiesto basado en las instrucciones contenidas en ella y en lo que se encuentre en el sistema de ficheros. Si prefieres escribir tu propio fichero de manifiesto, el formato es bastante sencillo: un fichero por línea, sólo ficheros normales (o enlaces simbólicos). Si proporcionas tu propio ‘MANIFEST’, hay que especificar todo: el juego predeterminado de ficheros anteriormente descrito no se aplica en este caso. La plantilla del manifiesto tiene una orden por línea, donde cada orden especifica un conjunto de ficheros que incluir o excluir de la distribución fuente. Por ejemplo, y retomando la propia plantilla de manifiesto de las Distutils: include *.txt recursive-include examples *.txt *.py prune examples/sample?/build

El significado debería resultar claro: incluir todos los ficheros de la raíz de la distribución que concuerden con *.txt, todos los ficheros bajo ‘examples’ que concuerden con *.txt o *.py, y excluir todos los ficheros que concuerden con examples/sample?/build. Todo ello se realiza tras el conjunto de inclusión estándar, por lo que se puede excluir ficheros del conjunto estándar con instrucciones explícitas en la plantilla del manifiesto (o se puede usar la opción --no-defaults para desactivar el conjunto estándar por completo). Hay varias órdenes más en el mini-lenguaje de la plantilla del manifiesto. Consulta la sección 9.4. El orden de las órdenes en la plantilla del manifiesto es relevante: inicialmente, tenemos la lista inicial predeterminada descrita anteriormente y cada orden va retirando o agregando ficheros de la lista. Una vez se ha procesado por completo la plantilla del manifiesto, eliminamos los ficheros que no deberían incluirse en la distribución de fuentes: • todos los ficheros del árbol de compilación de Distutils (por omisión ‘build/’) • todos los ficheros de directorios llamados ‘RCS’ o ‘CVS’ Ahora tenemos nuestra lista completa de ficheros, que se escribe en el manifiesto para futura referencia y se usa para construir el/los archivo/s final/es de la distribución. Se puede desactivar el conjunto predeterminado de ficheros incluidos con la opción --no-defaults y desactivar la lista estándar de exclusiones con la opción --no-prune. Siguiendo el propio fichero de manifiesto de las Distutils, vamos a trazar cómo construye la orden sdist la lista de ficheros que se incluyen en la distribución de fuentes de las Distutils: 1. incluir todos los ficheros fuente de Python de los subdirectorios ‘distutils’ y ‘distutils/command’ (porque los paquetes correspondientes a esos dos directorios fueron mencionados en la opción packages del guion de configuración, según lo contenido en la sección 3) 2. incluir ‘README.txt’, ‘setup.py’ y ‘setup.cfg’ (ficheros estándar) 3. incluir ‘test/test*.py’ (ficheros estándar) 4. incluir ‘*.txt’ de la raíz de la distribución (se volverá a encontrar ‘README.txt’ de nuevo, pero luego se desbrozan tales redundancias) 5. incluir cualquier cosa que concuerde con ‘*.txt’ o ‘*.py’ del subdirectorio‘examples’ y los interiores a éste, 6. excluir todos los ficheros de los subdirectorios que concuerden con ‘examples/sample?/build’ y los interiores a ellos—esto podría excluir ficheros incluidos por los dos pasos anteriores, por lo que es importante que la orden prune de la plantilla del manifiesto venga tras la orden recursive-include 7. excluir el árbol ‘build’ por completo y cualquier directorio ‘RCS’ o ‘CVS’ 8. en el árbol ‘examples’, incluir cualquier concordancia con ‘*.txt’ 5.1 Especificación de los ficheros a distribuir

13

9. en el árbol ‘examples’, incluir cualquier concordancia con ‘*.py’ 10. eliminar todos los ficheros de los directorios que concuerden con ‘examples/sample?/build’—esto podría excluir ficheros incluidos por los dos pasos anteriores, por lo que es importante que la orden prune de la plantilla del manifiesto venga tras las las dos órdenes recursive-include Al igual que en el guion de configuración, los nombres de ficheros y directorios de la plantilla del manifiesto deberían separarse por barras ‘/’siempre. Las Distutils se ocuparán de convertir las barras en la representación estándar de la plataforma de destino. De este modo, la plantilla del manifiesto es transportable entre diferentes sistemas operativos.

5.2

Opciones relativas al manifiesto

El curso normal de operaciones de la orden sdist es la siguiente: • si no existe el fichero de manifiesto, ‘MANIFEST’, leer ‘MANIFEST.in’ y crear ‘MANIFEST’ • si no existe ni ‘MANIFEST’ ni ‘MANIFEST.in’, crear un manifiesto con el conjunto predeterminado de ficheros3 • si ‘MANIFEST.in’ o el guion de configuración (‘setup.py’) son más recientes que ‘MANIFEST’, recrear ‘MANIFEST’ a partir de ‘MANIFEST.in’ • usar la lista actual de ficheros de ‘MANIFEST’ (recién generada o recuperada) para crear los archivos de distribución de fuentes Hay un par de opciones que modifican este comportamiento. Se puede usar --no-defaults y --no-prune para desactivar los conjuntos estándar de inclusión y exclusión. Observa que si no hay plantilla de manifiesto ni manifiesto y se usa --no-defaults, se obtiene un manifiesto vacío. Otro error de Distutils 0.9.2 y anteriores causa una excepción fatal en tal caso. Evitarlo es fácil: no reproduzcas el caso descrito. Además, es posible forzar la regeneración del manifiesto, por ejemplo, si se han añadido o eliminado ficheros o directorios que concuerdan con un patrón existente en el manifiesto, se debería regenerar el manifiesto: python setup.py sdist --force-manifest

O puede que sólo se desee (re)generar el manifiesto, sin crear una distribución de fuentes: python setup.py sdist --manifest-only

--manifest-only implica --force-manifest. -o es la abreviatura de --manifest-only y -f la de --force-manifest.

6

Creación de distribuciones binarias

Una “distribución compilada” se corresponde con los nombres comunes de “paquete binario” o “instalador” (dependiendo de tu bagaje cultural). No es necesario que sea binaria, sin embargo, porque es posible que sólo contenga código fuente de Python o bytecode. No lo llamamos paquete porque la palabra ya estaba tomada para otra cosa en Python. Instalador es un término específico de Windows. **do Mac people use it?** Una distribución compilada es la manera de facilitar más las cosas a los instaladores de la distribución de módulos: para los usuarios de Linux basado en RPM, es un RPM binario; para los usuarios de Windows, un instalador ejecutable; para 3 En las versiones de las Distutils hasta la 0.9.2 inclusive (Python 2.0b1), esta característica no funcionaba; se debe usar la opción -f (--forcemanifest) para superar el error.

14

6

Creación de distribuciones binarias

los usuarios de Debian, un paquete Debian, etc. Por supuesto, nadie será capaz de generar distribuciones para todas las plataformas habidas y por haber, por lo que las Distutils están diseñadas para permitir que los diseñadores de módulos se concentren en su especialidad, escribir código y generar las distribuciones de fuentes, mientras surge una especie nueva, los empaquetadores, para convertir las distribuciones de fuentes en distribuciones para tantas plataformas como sea posible. Por supuesto, el desarrollador de módulos puede ser su propio empaquetador. Podría ser un voluntario “de por ahí” que tuviera acceso a una plataforma a la que no tiene acceso el desarrollador original. Podría, incluso, ser software que periódicamente recopilase las distribuciones de fuentes y las compilase de tantos modos como fuera posible. Independientemente de la especie de la bestia en cuestión, un empaquetador usa el guion de configuración y la familia de órdenes bdist para generar distribuciones compiladas. Por ejemplo, si ejecuto la siguiente orden en el árbol de fuentes de las Distutils: python setup.py bdist

las Distutils generan mi distribución de módulos (en este caso, las propias Distutils ), generan un instalación “falsa” (también en el directorio ‘build’) y crea el tipo de distribución predeterminada de la plataforma. El formato predeterminado para las distribuciones compiladas es un fichero tar “bobo”4 en Unix y un sencillo instalador ejecutable en Windows. Por lo tanto, la orden anterior, en un sistema Unix, genera ‘Distutils-0.9.1.plat.tar.gz’; descomprimiendo el tar en el sitio correcto se instalan las Distutils, tal y como si se hubiera descargado la distribución de fuentes y se hubiera ejecutado python setup.py install. El sitio correcto es la raíz del sistema de archivos o el directorio prefix de Python, dependiendo de las opciones pasadas a la orden bdist_dumb; por omisión se generan distribuciones bobas relativas a prefix . Por supuesto, en el caso de las distribuciones de Python puras, esto no supone una ventaja sustancial, pero para las distribuciones no puras, puede suponer el salto entre que alguien sea capaz de usar tus extensiones o no lo sea. Y generar distribuciones compiladas “listas”, como los paquetes RPM o los instaladores ejecutables de Windows, facilita enormemente las cosas incluso si la distribución no incluye extensiones. La orden bdist tiene una opción --formats, parecida a la orden sdist, que se puede usar para elegir los tipos de distribución compilada a generar: por ejemplo, python setup.py bdist --format=zip

crearía, en un sistema Unix ‘Distutils-0.8.plat.zip’. Esto, nuevamente, se debería descomprimir en el sitio adecuado para instalar las Distutils. Los formatos disponibles para distribuciones compiladas son: Formato gztar ztar tar zip rpm srpm wininst

Descripción fichero tar gzipeado (‘.tar.gz’) fichero tar comprimido (‘.tar.Z’) fichero tar (‘.tar’) fichero zip (‘.zip’) RPM RPM de fuentes fichero ZIP autoextraíble para Windows

Notas (1),(3) (3) (3) (4) (5) (5) **to do!** (2),(6)

Notas: (1) predeterminado en Unix (2) predeterminado en Windows **to-do!** 4 el

fichero se considera “bobo” porque se debe desempaquetar en una ubicación específica para que funcione

15

(3) requiere utilidades externas: tar y gzip, bzip2 o compress (4) requiere utilidad zip o el módulo zipfile (que no es parte de la biblioteca estándar de Python) (5) requiere utilidad externa rpm, versión 3.0.4 o superior (usa rpm -version para averiguar qué versión tienes) (6) **requisitos de bdist_wininst?** No es necesario usar la orden bdist con la opción --formats, también se puede usar la orden que implementa directamente el formato deseado. Algunos de estas “sub-órdenes” bdist generan varios formatos similares; por ejemplo, la orden bdist_dumb genera todos los formatos de archivo “bobos” (tar, ztar, gztar y zip) y bdist_rpm genera los RPMs binarios y de fuentes. Las sub-órdenes bdist y los formatos que genera cada una son: Orden bdist_dumb bdist_rpm bdist_wininst

Formatos tar, ztar, gztar, zip rpm, srpm wininst

Las siguientes secciones proporcionan detalles de las diferentes órdenes bdist_*.

6.1

Creación de distribuciones compiladas bobas

**Need to document absolute vs. prefix-relative packages here, but first I have to implement it!**

6.2

Creación de paquetes RPM

El formato RPM es estándar en muchas distribuciones de Linux populares, incluyendo Red Hat, SuSE y Mandrake. Si tu entorno habitual se basa en RPM, es trivial crear paquetes RPM para otros usuarios de la misma distribución. Dependiendo de la complejidad de la distribución de módulos y de las diferencias entre distribuciones de Linux, puede que seas capaz de crear RPMs para otras distribuciones basadas en RPM. El modo usual de crear un RPM de tu distribución de módulos es ejecutar bdist_rpm: python setup.py bdist_rpm

o la orden bdist con la opción --format: python setup.py bdist --formats=rpm

La primera permite especificar opciones específicas de RPM, la segunda permite especificar más de un formato en una sola ejecución. Si necesitas las dos cosas, puedes especificar múltiples órdenes bdist_* y sus opciones: python setup.py bdist_rpm --packager="Juana Pérez <[email protected]>" \ bdist_wininst --target_version="2.0"

La creación de paquetes RPM va dirigida por un fichero ‘.spec’, del mismo modo en que el guion de configuración dirige las Distutils. Para facilitar la vida en la medida de lo posible, la orden bdist_rpm crea normalmente un fichero ‘.spec’ basado en la información proporcionada en el guion de configuración, la línea de órdenes o cualquier fichero de configuración de Distutils. Del guion de configuración se derivan varias opciones y secciones del fichero ‘.spec’:

16

6

Creación de distribuciones binarias

opción o sección del fichero ‘.spec’ de RPM Name Resumen (en el preámbulo) Versión Vendor Copyright Url %description (section)

Opción del guion de configuración de Distutils name descripción versión author y author_email o maintainer y maintainer_email licence url long_description

Además hay tres opciones más en los ficheros ‘.spec’ sin correspondencia en las opciones del guion de configuración. La mayoría de ellas se gestionan mediante opciones de la orden bdist_rpm: opción o sección del fichero ‘.spec’ de RPM Release Group Vendor Packager Provides Requires Conflicts Obsoletes Distribution BuildRequires Icon

opción bdist_rpm release group vendor

packager provides requires conflicts obsoletes distribution_name build_requires icon

valor predeterminado “1” “Development/Libraries” (see above) (none) (none) (none) (none) (none) (none) (none) (none)

Obviamente, proporcionar estas opciones en la línea de órdenes sería tedioso y propenso a errores, por lo que resulta mejor ponerlas en el fichero de configuración de la instalación, ‘setup.cfg’, consultar la sección 4. Si distribuyes o empaquetas muchas distribuciones de módulos de Python, es posible que te convenga poner las opciones que se apliquen a todas ellas en tu fichero personal de configuración de Distutils (‘~/.pydistutils.cfg’). Hay tres pasos para generar un paquete binario RPM y todos ellos los gestiona Distutils automáticamente: 1. crear un fichero ‘.spec’, que describe el paquete (análogo al guion de configuración de Distutils; mucha de la información de este fichero acaba en ‘.spec’) 2. crear el RPM fuente 3. crear el RPM “binario” (que puede contener, o no, código binario, dependiendo de si tu distribución de módulos contiene extensiones de Python) RPM suele juntar los dos últimos pasos. Al usar Distutils, se suelen juntar los tres. Si lo deseas, puedes separar estos tres pasos. Puedes usar la opción --spec-only para hacer que bdist_rpm sólo cree el fichero ‘.spec’ y termine. En este caso, el fichero ‘.spec’ quedará en el “directorio de distribución”, normalmente ‘dist/’, pero se puede personalizar mediante la opción --dist-dir. Normalmente, bdist_rpm deja el fichero ‘.spec’ en un directorio temporal bastante profundo **this isn’t implemented yet—is it needed?!** También se puede especificar un fichero ‘.spec’ a medida con la opción --spec-file. Utilizada junto con --spec-only, permite personalizar el fichero ‘.spec’ manualmente: > python setup.py bdist_rpm --spec-only # ...edit dist/FooBar-1.0.spec > python setup.py bdist_rpm --spec-file=dist/FooBar-1.0.spec

Puede que sea mejor sobreescribir la orden bdist_rpm estándar con una que escriba exactamente lo deseado en el fichero ‘.spec’ Consulta la sección 8 para obtener información sobre la extensión de las Distutils. 6.2 Creación de paquetes RPM

17

6.3

7

Creación de instaladores de Windows

Ejemplos

7.1

Distribución Python pura (por módulo)

7.2

Distribución Python pura (por paquete)

7.3

Módulo de extensión simple

7.4

Módulos de extensión múltiples

7.5

Todo junto

8

Extensión de las Distutils

8.1

Extensión de órdenes existentes

8.2

Implementación de nuevas órdenes

9 9.1

Referencia Compilación de módulos: la familia de órdenes build

build build_py build_ext build_clib

9.2

Instalación de módulos: la familia de órdenes install

La orden install asegura que las órdenes de compilación se han ejecutado y a continuación ejecuta las sub-órdenes install_lib, install_data y install_scripts. install_lib install_data Esta orden instala todos los ficheros de datos proporcionados con la distribución. install_scripts Esta orden instala todos los guiones (de Python) de la distribución.

18

9

Referencia

9.3

Acciones de limpieza: la orden clean

9.4

Creación de una distribución de fuentes: la orden sdist

**fragment moved down from above: needs context!** Las órdenes de la plantilla del manifiesto son: Command include pat1 pat2 ... exclude pat1 pat2 ...

recursive-include dir pat1 pat2 ...

recursive-exclude dir pat1 pat2 ...

global-include pat1 pat2 ...

global-exclude pat1 pat2 ...

prune dir graft dir

Description incluir todos los ficheros que concuerden con cualquiera de los patrones indicados excluir todos los ficheros que concuerden con cualquiera de los patrones indicados incluir todos los ficheros contenidos en dir que concuerden con cualquiera de los patrones indicados excluir todos los ficheros contenidos en dir que concuerden con cualquiera de los patrones indicados incluir todos los ficheros de cualquier parte del árbol de fuentes que concuerden con cualquiera de los patrones indicados excluir todos los ficheros de cualquier parte del árbol de fuentes que concuerden con cualquiera de los patrones indicados excluir todos los ficheros contenidos en dir incluir todos los ficheros contenidos en dir

Los patrones son del estilo de “glob” de Unix: * concuerda con cualquier secuencia de caracteres de nombre de fichero normales, ? concuerda con un solo carácter normal de nombre de fichero y [rango] concuerda con cualquiera de los caracteres de rango (por ejemplo, a-z, a-zA-Z, a-f0-9_.)5 . La definición de “carácter normal de nombre de fichero” depende de la plataforma: En Unix es cualquier cosa excepto la barra. En Windows, cualquier cosa excepto la barra o los dos puntos. En Mac, cualquier cosa excepto los dos puntos. **Windows and Mac OS support not there yet**

9.5

Creación de una distribución compilada: la familia de órdenes bdist

blib blib_dumb blib_rpm blib_wise

5 N. del T.: Lo de las eñes y acentos es un asunto aparte. Mi opinión personal es que los nombres de ficheros para distribución sólo deberían contener caracteres ASCII, sin acentos ni eñes.

9.3 Acciones de limpieza: la orden clean

19

Related Documents

Python Para Todos Ii
December 2019 12
Python Para Todos
December 2019 18
Para Todos....
April 2020 17
Python Para Zope
October 2019 58

More Documents from "Manuel"

Cms De Ml Descripcion
December 2019 33
Plataformaplonezope
May 2020 29
Php Perfect Form
December 2019 37
Primer
December 2019 57
Guia_familysearch
May 2020 29