¿Cómo construir una distribución fuente sin usar el archivo setup.py?

10

Con la siguiente estructura de paquete

.
├── my_package
   └── __init__.py
├── setup.cfg
└── setup.py

Contenido de setup.py

from setuptools import setup
setup()

Contenido de setup.cfg

[metadata]
name = my_package
version = 0.1

[options]
packages = find:

Puedo construir una rueda o una distribución de origen para my_packageesto

pip wheel --no-deps -w dist .
# generates file ./dist/my_package-0.1-py3-none-any.whl
python setup.py sdist
# generates file ./dist/my_package-0.1.tar.gz

Pero de acuerdo con el mantenedor de setuptools , una configuración de compilación declarativa es ideal y usar una compilación imperativa será un olor a código. Entonces reemplazamos setup.pycon pyproject.toml:

.
├── my_package
   └── __init__.py
├── setup.cfg
└── pyproject.toml

Contenido de pyproject.toml

[build-system]
build-backend = "setuptools.build_meta"
requires = ["setuptools", "wheel"]

Y aún puede construir una rueda de la misma manera que antes, funciona. Pero sdist no funciona:

python: can't open file 'setup.py': [Errno 2] No such file or directory

Entonces, ¿cómo debería realmente construir el archivo .tar.gz usando setuptools ? ¿Cuál es la herramienta orientada al usuario para crear sdist? No quiero cambiar el backend de compilación. Parece que otras herramientas de empaque escriben sus propios puntos de entrada de compilación, pero pensé que el objetivo de definir un sistema de compilación declarativo en los metadatos era para que no tuvieras que ponerte en práctica con el sistema de compilación, aprendiendo cómo cada uno diferente herramienta de empaquetado espera ser invocada o tener que ingresar al intérprete y llamar a una API de Python manualmente. Pero el PEP para los requisitos del sistema de construcción tiene más de 2 años. ¿Me estoy perdiendo algo obvio aquí?

¿Cómo construir una distribución fuente sin usar el setup.pyarchivo?

ornitorrinco
fuente

Respuestas:

10

Este es un tema algo controvertido, y la respuesta por el momento es que no hay una sola herramienta en la que todos estén de acuerdo es la "forma correcta" de construir distribuciones de origen, ni cuál sería esa herramienta. Puede ver un hilo largo al respecto en el discurso de Python Packaging .

No me atrevo a dar demasiados consejos envasado en formatos duraderos debido a que las arenas siempre están cambiando, pero a partir de noviembre 2019, setup.py sdistestá no descartadas, pero tiene todas las desventajas que la PEP 517 y PEP 518 fueron destinados a la solución - a saber, que usted tiene para crear el entorno de compilación usted mismo (y conocer todas las dependencias de compilación), y solo funciona con setuptools / distutils y sus equivalentes.

No es una recomendación "oficial", pero el mejor reemplazo actual para setup.py sdiste setup.py bdist_wheelinvoca la versión de línea de comandos de pep517. El reemplazo de sdistes:

python -m pep517.build --source .

Puede construir la rueda y la distribución de origen al mismo tiempo así:

python -m pep517.build --source --binary .

Así es como construyo mis paquetes compatibles con PEP 517.

Esto requiere que su proyecto tenga un pyproject.toml, y el pyproject.tomldebe tener build-system.requiresy build-system.build-backendclaves, pero funcionará para cualquier proyecto con un backend compatible con PEP 517 (incluido flit).

Otras herramientas :

¿Por qué no usar flito poetryo hatch? Esas herramientas están disponibles para aquellos que desean usarlas, pero no son una respuesta a esta pregunta . Esta pregunta es acerca de proyectos construidos con setuptoolsese setup.cfgformato declarativo . Ni flittampoco poetryactúan como front-end genéricos de compilación PEP 517, por lo que solo funcionan como comandos de compilación para proyectos que utilizan sus respectivos backends.

Soy lo suficientemente familiarizado con hatchdecir si es o no puede gestionar proyectos con backends otros que setuptools, pero (de nuevo, en noviembre de 2019), es no una interfaz de PEP 517, y no va a funcionar si no tiene a setup.py(generará el error "no se puede abrir el archivo setup.py" e ignorará su pyproject.tomlarchivo).

Pablo
fuente
¿Por qué centrarse en lo pep517.buildque solo se entiende como un experimento, una muleta temporal cuando hay herramientas productivas como revoloteo, poesía, escotilla y probablemente aún más?
sinoroc
1
Porque fue un experimento exitoso en mi estimación (yo y muchas otras personas de PyPA lo usamos), ya que tiene la semántica adecuada para el trabajo, y porque es el único front-end de construcción PEP 517 de propósito general que conozco. flit y poesía están integrados verticalmente en el sentido de que esperan que uses su backend. la escotilla parece hacer muchas otras cosas. pep517.buildes una herramienta simple creada exactamente para este propósito.
Paul
Ah cierto, buen punto. Me estaba centrando en la construcción de back-end. Y en realidad pensé que pep517.buildera uno de ellos. Pero en absoluto, en realidad es un front-end de compilación. Además, la escotilla no está lista para PEP517 como veo ahora.
sinoroc
1
He actualizado mi respuesta para responder a su pregunta.
Paul
Si perfecto. Borro mi respuesta.
sinoroc
-1

No hay nada "obvio" cuando se trata de empaquetado de Python. De hecho, por el momento, al menos si está usando distutils / setuptools, es necesario crear un setup.pyarchivo (casi) vacío , incluso si está usando un declarativo completo setup.cfg:

#!/usr/bin/env python
from setuptools import setup
setup()

Yo tambien lo recomiendo chmod +x setup.py.

En este caso, solo está escribiendo el "punto de entrada" en el sistema de compilación, y setup()es solo la main()función para ello, pero ahora setup()se pueden leer todos los argumentos que tradicionalmente se pasaron a setup.cfg.

Ahora aún puede usar setup.py sdistsi desea hacer un tarball fuente:

./setup.py sdist

También puede probar uno de los sistemas de compilación alternativos que están habilitados a través de pyproject.toml, como Flit .

Iguananaut
fuente
No estoy seguro de por qué esto se está rechazando; es básicamente correcto incluso si hay otras soluciones.
Iguananaut
2
El título de la pregunta es "¿Cómo construir una distribución fuente sin usar el archivo setup.py?" Esta respuesta parece demostrar simplemente "aquí está cómo recrear el mismo archivo setup.py que acaba de eliminar", lo cual no es útil.
ornitorrinco
Sí, pero eso se basó en un malentendido de que escribir una declaración setup.cfgsignifica que setup.pyya no es necesario usar setuptools, lo cual no es cierto. El hecho de que el título de la pregunta sea engañoso no significa que la respuesta lo sea. Escribieron en el cuerpo de la pregunta "Entonces, ¿cómo debería realmente construir el archivo .tar.gz usando setuptools ?" que esto responde correctamente.
Iguananaut
1
En realidad es verdad. setuptools no requiere un archivo setup.py si está utilizando PEP 517.
Paul
"si está usando PEP 517" Excepto que la mayoría de las personas no lo están. Todavía es provisional, y apenas se menciona en packaging.python.org . No es algo que tendría a menos que sepa ir a buscarlo. Si solo desea que las herramientas de configuración funcionen como siempre solía hacerlo, esto es correcto.
Iguananaut