Cómo organizar los módulos de Python para que PyPI sea compatible con 2.x y 3.x
python-3.x software-distribution (2)
Tengo un módulo de Python que me gustaría subir a PyPI. Hasta ahora, está funcionando para Python 2.x. No debería ser demasiado difícil escribir una versión para 3.x ahora.
Pero, después de seguir las pautas para hacer módulos en estos lugares:
no me queda claro cómo admitir múltiples distribuciones de origen para diferentes versiones de Python, y no está claro si / cómo PyPI podría soportarlo. Me imagino que tendría un código separado para:
- 2.x
- 2.6 (tal vez, como un caso especial para usar la nueva API de búfer)
- 3.x
¿Cómo es posible configurar un módulo de Python en PyPI para que alguien pueda hacer lo siguiente?
easy_install modulename
e instalará lo correcto si el usuario está utilizando 2.x o 3.x?
La solución más simple es usar una única fuente de distribución.
Descubrí que setup.py
para httplib2
parece tener una forma elegante de admitir Python 2.xy 3.x. Entonces decidí copiar ese método.
La tarea es crear un solo setup.py
para la distribución de paquetes que funcione con todas las distribuciones de Python admitidas. Luego, con el mismo setup.py
, puedes hacer:
python2 setup.py install
tanto como
python3 setup.py install
Debería ser posible mantener setup.py
suficientemente simple como para ser analizado con todas las distribuciones de Python soportadas. Lo he hecho con éxito con un paquete de cobs
que admite 2.4 a 2.6 y 3.1. Ese paquete incluye código puro de Python (código separado para Python 2.xy 3.x) y extensiones C, escritas por separado para 2.x y 3.x.
Para hacerlo:
1) Puse el código Python 2.x en un subdirectorio python2
y el código Python 3.x en un subdirectorio python3
.
2) Puse el código de extensión C para 2.x y 3.x en un directorio src
en python2
y python3
.
Entonces, la estructura del directorio es:
root
|
+--python2
| |
| +--src
|
+--python3
| |
| +--src
|
+--setup.py
+--MANIFEST.in
3) En setup.py
, tenía estas líneas cerca de la parte superior:
if sys.version_info[0] == 2:
base_dir = ''python2''
elif sys.version_info[0] == 3:
base_dir = ''python3''
4) En la llamada a la setup
, especifiqué los paquetes como normales:
setup(
...
packages=[ ''cobs'', ''cobs.cobs'', ''cobs.cobsr'', ],
5) Especifiqué el directorio base para el código de Python usando una opción package_dir
(consulte el paso 3 para base_dir
):
package_dir={
''cobs'' : base_dir + ''/cobs'',
},
6) Para las extensiones C, di el camino:
ext_modules=[
Extension(''cobs.cobs._cobs_ext'', [ base_dir + ''/src/_cobs_ext.c'', ]),
Extension(''cobs.cobsr._cobsr_ext'', [ base_dir + ''/src/_cobsr_ext.c'', ]),
],
Eso fue todo para setup.py
. El archivo setup.py
es analizable por Python 2.xy 3.x.
7) Finalmente, si construyes una distribución fuente usando:
python2 setup.py sdist
entonces, por defecto, solo ingresará los archivos que se necesitan específicamente para construir para ese Python. Por ejemplo, en el caso anterior, solo obtendría los archivos de python2
en la distribución de origen, pero no los de python3
. Pero para una distribución de fuente completa, desea incluir los archivos para 2.x y 3.x. Para hacerlo, crea un archivo MANIFEST.in
que contenga algo como esto:
include *.txt
recursive-include python2 *
recursive-include python3 *
Para ver lo que hice, vea el código fuente de las cobs
en PyPI o BitBucket .