¿Qué podemos poner en un archivo setup.py
para evitar que pip recopile e intente instalar un paquete cuando se usa una versión de Python no compatible?
Por ejemplo magicstack
es un proyecto listado con el clasificador trove:
Programming Language :: Python :: 3 :: Only
Así que espero el siguiente comportamiento si pip --version
está vinculado a python 2.7:
$ pip install magicstack Collecting magicstack Could not find a version that satisfies the requirement magicstack (from versions: ) No matching distribution found for magicstack
Pero el comportamiento real es que pip recopila una versión, la descarga, intenta instalarla y falla. Hay otras versiones solo de curio
, por ejemplo, Curio, que en realidad se instalan bien, porque setup.py
no usó nada específico de Python 3, solo para fallar en el momento de la importación cuando se usa alguna sintaxis solo de Python 3. ¡Y estoy seguro de que hay paquetes que se instalan bien, importan bien y tal vez solo fallan en el tiempo de ejecución!
¿Cuál es el método correcto para especificar sus versiones compatibles de Python de una manera que pip respete? Encontré una solución alternativa, que consiste en cargar solo un archivo de rueda y negarme a cargar una distribución .tar.gz, pero me interesaría saber la solución correcta.
Editar: ¿Cómo sabe pip que no debe descargar la distribución de la rueda si Python/os/architecture no coincide? ¿Solo usa la convención de nombre de archivo .whl o hay algo más sofisticado que eso que sucede detrás de escena? ¿Podemos de alguna manera dar los metadatos a una distribución fuente para hacer que pip haga lo correcto con las cargas .tar.gz?
Hay una manera correcta de hacer esto, pero desafortunadamente pip solo comenzó a admitirlo en la versión 9.0.0 (lanzada el 2016-11-02), por lo que los usuarios con versiones anteriores de pip continuarán descargando paquetes independientemente de lo que haga Python. versión para la que son.
En su archivo setup.py
, pase setup()
un argumento python_requires
que enumere las versiones de Python compatibles con su paquete como un especificador de versión PEP 440 . Por ejemplo, si su paquete es solo para Python 3+, escriba:
setup( ... python_requires='>=3', ... )
Si su paquete es para Python 3.3 y versiones posteriores, pero aún no está dispuesto a comprometerse con el soporte de Python 4, escriba:
setup( ... python_requires='~=3.3', ... )
Si su paquete es para Python 2.6, 2.7 y todas las versiones de Python 3 a partir de 3.3, escriba:
setup( ... python_requires='>=2.6, !=3.0.*, !=3.1.*, !=3.2.*, <4', ... )
Y así.
Una vez que haya hecho eso, deberá actualizar su versión de setuptools a al menos 24.2.0 para que se procese el argumento python_requires
; las versiones anteriores simplemente lo ignorarán con una advertencia. Todos los sdists y ruedas de su proyecto construidos posteriormente contendrán los metadatos relevantes que le indican a PyPI que le diga a pip para qué versiones de Python son.
La distribución magicstack
en pypi está rota. Está fallando porque la distribución fuente no contiene un paquete magicstack
a pesar de que setup.py
para la distribución fuente dice que debería.
Siempre que pypi contenga una distribución fuente (p. ej., .tar.gz
, .zip
), pip la descargará si no puede encontrar una distribución binaria coincidente (p. ej., .egg
, .whl
) para su versión de python/os/architecture .
Una opción es cargar solo distribuciones binarias a PyPI (preferiblemente wheels
). La otra opción es verificar sys.version
en su setup.py
para ver si hay versiones compatibles y, de lo contrario, generar una excepción.