Como criar uma distribuição de origem sem usar o arquivo setup.py?

10

Com a seguinte estrutura de pacotes

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

Conteúdo de setup.py

from setuptools import setup
setup()

Conteúdo de setup.cfg

[metadata]
name = my_package
version = 0.1

[options]
packages = find:

Eu posso construir rodas ou uma distribuição de fontes para my_packageisso

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

Mas, de acordo com o mantenedor do setuptools , uma configuração de compilação declarativa é ideal e usar uma compilação imperativa será um cheiro de código. Então substituímos setup.pypor pyproject.toml:

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

Conteúdo de pyproject.toml

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

E você ainda pode montar uma roda da mesma maneira que antes, ela funciona. Mas sdist não funciona:

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

Então, como você realmente deve criar o arquivo .tar.gz usando o setuptools ? Qual é a ferramenta voltada ao usuário para criar sdist? Não quero alterar o back-end da compilação. Parece que outras ferramentas de empacotamento escrevem seus próprios pontos de entrada de construção, mas achei que o objetivo principal de definir um sistema declarativo de construção nos metadados era para que você não precisasse trabalhar com o sistema de construção, aprendendo como cada espera-se que uma ferramenta de empacotamento diferente seja chamada ou precise entrar no interpretador e chamar uma API Python manualmente. Mas o PEP para requisitos de sistema de compilação já tem mais de 2 anos. Estou perdendo algo óbvio aqui?

Como criar uma distribuição de origem sem usar o setup.pyarquivo?

ornitorrinco
fonte

Respostas:

10

Esse é um tópico um tanto controverso, e a resposta no momento é que não existe uma única ferramenta que todos concordem que seja o "caminho certo" para criar distribuições de código-fonte, nem qual seria essa ferramenta. Você pode ver uma longa discussão sobre isso no discurso do Python Packaging .

Hesito em dar conselhos demais embalagens em formatos duráveis porque as areias estão sempre mudando, mas a partir de novembro 2019, setup.py sdisté não obsoleto, mas não tem todas as desvantagens que PEP 517 e PEP 518 foram destinados a correção - ou seja, que você tem criar você mesmo o ambiente de construção (e conhecer todas as dependências de construção) e funciona apenas com setuptools / distutils e seus equivalentes.

Não é uma recomendação "oficial", mas a melhor alternativa atual setup.py sdiste setup.py bdist_wheelestá invocando a versão da linha de comando do pep517. A substituição para sdisté:

python -m pep517.build --source .

Você pode construir a roda e a distribuição da fonte ao mesmo tempo:

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

É assim que eu construo meus pacotes compatíveis com o PEP 517.

Isso requer que seu projeto tenha um pyproject.toml, e pyproject.tomldeve ter build-system.requirese build-system.build-backendchaves, mas funcionará para qualquer projeto com um back-end compatível com o PEP 517 (inclusive flit).

Outras ferramentas :

Por que não usar flitou poetryou hatch? Essas ferramentas estão disponíveis para quem deseja usá-las, mas não são uma resposta para esta pergunta . Esta pergunta é feita sobre projetos criados com setuptoolso uso do setup.cfgformato declarativo . Nem flitnem poetryagir como PEP 517 front-ends de compilação genéricos, e assim eles única obra como comandos de compilação para projetos usando seus respectivos backends.

Eu sou o suficiente para não familiarizados com hatcha dizer se é ou não possível gerenciar projetos com backends outros que setuptools, mas (novamente, a partir de novembro de 2019), é não um frontend PEP 517, e não vai funcionar se você não tiver a setup.py(gerará o erro "não é possível abrir o arquivo setup.py" e ignorará seu pyproject.tomlarquivo).

Paulo
fonte
Por que focar no pep517.buildque é apenas um experimento, uma muleta temporária quando existem ferramentas produtivas como esvoaçante, poesia, escotilha e provavelmente até mais?
sinoroc
11
Porque foi um experimento bem-sucedido em minha opinião (eu e muitas outras pessoas do PyPA o usamos), pois possui a semântica correta para o trabalho e porque é o único front-end de construção geral do PEP 517 que eu conheço. flit e poesia são verticalmente integrados, na medida em que esperam que você use o back-end. hachura parece fazer muitas outras coisas. pep517.buildé uma ferramenta simples criada exatamente para esse fim.
Paul
Ah certo, bom ponto. Eu estava focado nos back-ends de construção. E eu realmente pensei que pep517.buildera um deles. Mas de maneira alguma, na verdade, é um front-end de compilação. A hachura também não está pronta para o PEP517, como eu vejo agora.
sinoroc 7/11/19
11
Atualizei minha resposta para responder à sua pergunta.
Paul
Sim, perfeito. Eu apago minha resposta.
sinoroc 7/11/19
-1

Não há nada "óbvio" quando se trata de embalagens Python. De fato, por enquanto, pelo menos se você estiver usando distutils / setuptools, é necessário criar um setup.pyarquivo (quase) vazio , mesmo se você estiver usando um totalmente declarativo setup.cfg:

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

Eu também recomendo chmod +x setup.py.

Nesse caso, você está apenas escrevendo o "ponto de entrada" para o sistema de construção e setup()é apenas a main()função para ele - mas agora todos os argumentos que eram tradicionalmente passados setup()podem ser lidos setup.cfg.

Agora você ainda pode usar setup.py sdistse quiser criar um tarball de origem:

./setup.py sdist

Você também pode tentar um dos sistemas de compilação alternativos ativados via pyproject.toml, como o Flit .

Iguananaut
fonte
Não sei por que isso está sendo votado; é basicamente correto, mesmo se houver outras soluções.
Iguananaut 8/11/19
2
O título da pergunta é "Como criar uma distribuição de origem sem usar o arquivo setup.py?" Esta resposta parece apenas demonstrar "aqui está como recriar o mesmo arquivo setup.py que você acabou de excluir", o que não é útil.
ornitorrinco
Sim, mas isso foi baseado em um mal-entendido de que escrever um declarativo setup.cfgsignifica que setup.pynão é mais necessário usar o setuptools, o que não é verdade. Só porque o título da pergunta é enganoso, não significa que a resposta seja. Eles escreveram no corpo da pergunta "Então, como você realmente deve criar o arquivo .tar.gz usando o setuptools ?" que isso responde corretamente.
Iguananaut 9/11/19
11
Na verdade é verdade. não setuptools não requer um arquivo setup.py se você estiver usando PEP 517.
Paul
"se você estiver usando o PEP 517", exceto que a maioria das pessoas não está. Ainda é provisório e quase não é mencionado em packaging.python.org . Não é algo que você teria, a menos que saiba procurar. Se você apenas deseja que as ferramentas de instalação funcionem, como sempre, isso está correto.
Iguananaut 19/11/19