pyproject.
toml
Live de Python #257
[Link]
[Link]
Poetry é melhor PDM, pfv
Já ouviu a
palavra do
Eu uso pip conda?
hatch! rye!
[Link]
USE O
[Link]
Minha resposta padrão para tudo
Q?
[Link]/livedepython [Link]@[Link] [Link]/dunossauro
Ajude o projeto <3
Ademar Peixoto, Adilson Herculano, Alemao, Alexandre Harano, Alexandre Lima, Alexandre Takahashi, Alexandre Villares, Alfredo
Braga, Alisson Souza, Alysson Oliveira, Andre Azevedo, Andre Mesquita, Andre Paula, Aniltair Filho, Antônio Filho, Arnaldo Turque,
Aslay Clevisson, Aurelio Costa, Bárbara Grillo, Ber_dev_2099, Bernardo Fontes, Bruno Almeida, Bruno Barcellos, Bruno Batista, Bruno
Freitas, Bruno Ramos, Caio Nascimento, Carlos Ramos, Cristian Firmino, Daniel Bianchi, Daniel Freitas, Daniel Real, Daniel
Wojcickoski, Danilo Boas, Danilo Silva, David Couto, David Kwast, Davi Souza, Dead Milkman, Denis Bernardo, Diego Guimarães, Dino,
Edgar, Edilson Ribeiro, Emerson Rafael, Ennio Ferreira, Erick Andrade, Érico Andrei, Everton Silva, Fabio Barros, Fábio Barros, Fabio
Valente, Fabricio Biazzotto, Felipe Augusto, Felipe Rodrigues, Fernanda Prado, Fernando Celmer, Flávio Meira, Francisco Silvério,
Frederico Damian, Gabriel Espindola, Gabriel Mizuno, Gabriel Moreira, Gabriel Paiva, Gabriel Ramos, Gabriel Simonetto, Giovanna
Teodoro, Giuliano Silva, Guilherme Beira, Guilherme Felitti, Guilherme Gall, Guilherme Ostrock, Guilherme Piccioni, Guilherme Silva,
Gustavo Suto, Haelmo Almeida, Harold Gautschi, Heitor Fernandes, Helvio Rezende, Henrique Andrade, Hiago Couto, Higor Monteiro,
Igor Taconi, Janael Pinheiro, Jean Victor, Jefferson Antunes, Joelson Sartori, Jonatas Leon, Jônatas Oliveira, Jônatas Silva, Jorge
Silva, Jose Barroso, José Gomes, Joseíto Júnior, Jose Mazolini, Josir Gomes, Juan Felipe, Juliana Machado, Julio Batista-silva, Julio
Franco, Júlio Gazeta, Júlio Sanchez, Kaio Peixoto, Leandro Silva, Leandro Vieira, Leonardo Mello, Leonardo Nazareth, Lucas Carderelli,
Lucas Lattari, Lucas Mello, Lucas Mendes, Lucas Nascimento, Lucas Schneider, Lucas Simon, Luciano Filho, Luciano Ratamero,
Luciano Teixeira, Luis Eduardo, Luiz Carlos, Luiz Duarte, Luiz Lima, Luiz Paula, Mackilem Laan, Marcelo Araujo, Marcio Moises, Marcio
Silva, Marco Mello, Marcos Gomes, Marina Passos, Mateus Lisboa, Matheus Ferreira, Matheus Silva, Matheus Vian, Mírian Batista,
Mlevi Lsantos, Murilo Carvalho, Murilo Viana, Nathan Branco, Ocimar Zolin, Otávio Carneiro, Pedro Gomes, Pedro Henrique, Pedro
Pereira, Peterson Santos, Rafael Araújo, Rafael Faccio, Rafael Lopes, Rafael Romão, Rafael Silva, Raimundo Ramos, Ramayana
Menezes, Renato José, Renato Moraes, Renato Oliveira, Renê Barbosa, Rene Pessoto, Renne Rocha, Ricardo Combat, Ricardo Silva,
Rinaldo Magalhaes, Riverfount, Rjribeiro, Rodrigo Barretos, Rodrigo Oliveira, Rodrigo Quiles, Rodrigo Santana, Rodrigo Vaccari,
Rodrigo Vieira, Rogério Nogueira, Rui Jr, Samanta Cicilia, Samuel Santos, Santhiago Cristiano, Selmison Miranda, Téo Calvo, Thiago
Araujo, Thiago Borges, Thiago Curvelo, Tony Dias, Tyrone Damasceno, Valdir, Valdir Tegon, Vinícius Costa, Vinicius Stein, Washington
Teixeira, Willian Lopes, Wilson Duarte, Zeca Figueiredo
Obrigado você
Roteiro
1. Entendendo o problema 3. [Link]
A complexidade do ecossistema do PEP-517, PEP-518, PEP-621, PEP-658
python
2. Uma breve, mas longa
história 4. O que ainda deve ser feito?
O legado das aplicações que vieram Nem todos os problemas estão
antes e ainda são mantidos resolvidos
Proble
mas!!! Tudo que envolve
empacotamento
Python tem um ecossistema complexo
Python tem um ecossistema complexo
Python roda em lugares muito diferentes
Python tem diferentes implementações
Python está contido em muitos lugares
Cont
exto Um pouco de
história!
Eu sou um pythonista relativamente novo, muitas das
coisas que eu vou falar aqui são por que eu li ou ouvi
pessoas mais antigas na linguagem comentado!
Um ponto!
● Python foi criado em 1991, numa situação muito diferente de
linguagens "modernas".
● A distribuição de pacotes era completamente difente!
● Python não contava com uma forma padrão de distribuição de
pacotes. Até por que, vai por onde?
1991
● Um lugar para indexar pacotes foi criado, Vaults of parnassus
???
● Foi criado um SIG (Special Interest Groups) para distribuição de
pacotes
● Disso surgiu o Distutils
● Ferramenta embutida até a versão 3.11
● Introdução do arquivo [Link]
● [Link] era responsável pelo build e pala instalação do pacote
● Os formatos de código (sdist) e binário (bdist) foram convencionados
1998 - 2000
Distuils
Distuils
metadados!
Distuils
Distuils
● Início do Cheese Shop (2002)
● Publicação do Python Package Index [PyPI] (2003)
● Ainda era só um index
● Os pacotes só começaram a ser armazenados em 2005
● PEP 301 conta sobre os padrões
2002 - 2003
Cheese Shop sketch (1972) - Monty Python
● Introdução do setuptools
● Estende as funcionalidades do distutils
● Declaração de bibliotecas extenas no [Link]
● easy_install foi apresentado como uma ferramenta simples de
instalação de pacotes (só instalar, não dava pra desinstalar ???)
● Introdução do formato eggs para binários
○ Eggs são para python como jars estão para java
● setuptools ainda é a ferramenta "padrão" (ela se adaptou a todas as mudanças)
2004
Setuptools
Dependencias!
Setuptools
easy_install
● Introdução do virtualenv
● virtualenv vs -m venv
○ O venv embutido é uma parte da biblioteca virtualenv
● O venv foi somente introduzido na biblioteca padrão em 2012 [3.3]
● Na live de python #191 discutimos sobre ele!
2007
● Introdução do Pip Install Package (pip)
● Junto com o pip é indroduzido o [Link]
● Instala, desinstala e atualiza
● Ambiente concreto, dependências concretas!
2008
[Link]
O arquivo de requerimentos é uma forma de padronizar um ambiente
determinístico. Com dependências concretas.
Especificação para a "pinagem" de versão foi introduzida na PEP-440 [2013]
Concreto vs Abstrato
Pacote A Pacote B
Pacote C Pacote D
Pacote E
● Minestério das instalações [PyPA] (Python Packaging Authority)
● Um grupo de pessoas voluntarias que cuida do:
○ setuptools
○ virtualenv
○ PyPI
○ … Ainda tem mais por vir
● Lidar com a complexidade do ecossistema!
2011
● O padrão wheel (extensão .whl)
● Padronização dos pacotes binários (bdist)
● Pacotes por:
○ sistema (windows, mac, linux, …)
○ versão do python
○ plataforma (pypy, cpython, …)
○ Exemplo Numpy
● PEP-427
2012 - 2014
Ponto importante sobre o wheel
Onde os mais importantes agora são:
● distribution: o nome do pacote
● version: a versão do pacote
● python tag: Versão do python em que o pacote deve ser usado
● platform tag: tag para um sistema operacional específico. Para todos
é `any`
As tags abi são um assunto a parte. Na [documentação do PyPA existe bastante insumo
para isso]
Exemplo
distribuição
doNumpy
pyproj
ect
.toml Uma especificação!
A especificação
O que temos até agora aprovado são 4 PEPs:
● 517 [2015-2017]: Backend e frontend de build
● 518 [2016]: Criação do [Link]
● 621[2020]: Metadados
● 660 [2021]: Pacotes editáveis
PEP 518 - Um sistema mínimo para builds
● A ideia principal é mostrar como um pacote deve especificar suas
próprias dependências de build. O que é necessário que o ambiente
tenha, para que o build possa ser feito.
● Fica especificado que um arquivo chamado `[Link]` será
utilizado para esse fim.
● O arquivo no `toml` foi escolhido por ser bom de ler/escrever por
humanos (diferente do JSON), flexível o suficiente (diferente do
configparser), é originado por um padrão (também diferente do
configparser) e não é complicado (como YAML).
TOML
Implementa diversos tipos de dados, sendo o primordial para o pyproject
as tables:
Equivalente a:
Especificação de build
A especificação se baseia em duas tables, uma para o sistema de build
(build-system) e outra para ferramentas em geral (tool).
● A tabela referente ao sistema de builds tem uma única chave
chamada requires, que será um array de todas as ferramentas que
devem estar presentes no sistema no momento do build.
Desta forma, caso essas ferramentas não existam no ambiente, alguma
ferramenta pode instalar (por padrão, o pip)
A tabela tool
Diferente da tabela de `build-system` que tem objetivos relacionados ao
propósito da PEP, a tabela `tool` pode ser usada por qualquer ferramenta
que relacionada ao seu projeto python, não somente a ferramentas de
build.
A recomendação de uso é que cada ferramenta crie sua própria subtabela
de tools segunda por `.ferramenta`.
Alguns exemplos:
● Pytest: Biblioteca de testes
● Ruff: Linter e formatador
● towncrier: Gerador de changelogs (merece uma live?)
● mypy: Checador de tipos
Um exemplo
Ferramentas de build + tool
As ferramentas de build também usam esses campos:
● poetry
● pdm
● hatch
● rye
● setuptools
● flit
● …
PEP 621 - Metatados para o sistema de build
Embora um sistema mínimo de build tenha sido criado e bem utilizado por
ferramentas. Alguns pontos do modelo "agnóstico" ainda não estavam
sendo levado em consideração. Os metadados do projeto.
Os backends não tinham um padrão definido para o `nome` do pacote, sua
`versão`, seus `scripts`, duas `dependencias`, etc. O que tornava a
migração entre backends um grande trabalho e diminuí a facilidade
"pregada" pela PEP-518.
Tabela [project]
A PEP especifica uma nova tabela opcional no `[Link]` chamada
project. Que agrupa todos os metadados sem depender de uma tabela
[[Link]]
A especificação diz que os valores atrelados as chaves podem ser de dois
tipos:
● Estaticos: Metadados especificados no próprio arquivos e que não
podem ser alterados
● Dinâmicos: Metadados marcados em um array com a chave
`dynamic`, que serão fornecidos pelo build-system
Chaves obrigatórias
Somente as chaves name e version são consideradas obrigatórias
Chaves opcionais
Entre as chaves opcionais estão uma grande variedade de chaves, como:
● description: String de descrição do pacote
● reame: String com o caminho do arquivo `'[Link]'`
● license: Subtabela indicando o arquivo
○ `{file = '[Link]'}`
● authors: Array de subtabelas inline
○ `[{name = 'duduzinho', email = 'test@mail'}]`
● manteiners: Array de subtabelas inline
○ `[{name = 'duduzinho', email = 'test@mail'}]`
> As definições atualizadas de metadados podem ser encontradas aqui:
[Link]
claring-project-metadata-the-project-table
Dependências
Nas chaves opcionais eu gostaria de destacar o campo que especifica as
dependências do projeto. Um array listando todos os pacotes que nosso
pacote depende (uma espécie de requirements):
A magia acontecendo!
Agora, com um build-system + project. Podemos usar o pip para instalar
nosso pacote local, baixar e instalar as dependências.
A magia acontecendo!
Agora, com um build-system + project. Podemos usar o pip para instalar
nosso pacote local, baixar e instalar as dependências.
Subtabelas de project
Dentro da tabela `project` você pode definir diversas outra tabelas, vou
destacar as que considero mais interessantes agora:
● optional-dependencies: Uma tabela que cria grupos de dependências.
Como dependências de testes, documentação e etc…
● scripts: Executáveis do pacote.
A subtabela de dependências opcionais:
Subtabelas de project
Dentro da tabela `project` você pode definir diversas outra tabelas, vou
destacar as que considero mais interessantes agora:
● optional-dependencies: Uma tabela que cria grupos de dependências.
Como dependências de testes, documentação e etc…
● scripts: Executáveis do pacote.
A subtabela de dependências opcionais:
Subtabela de scripts
A subtabela de `scripts` também é interessante para criar CLIs ou entradas
para GUIs diretamente do pacote:
PEP 517 - O sistema de builds
O objetivo de definir um formato de build independente das ferramentas já
existentes. Como `buildutils` e `setuptools`, definidas pelo `distutils-sig`. Se
você quiser usar outra coisa, isso deve ser fácil de fazer e também deve
ser fácil para novas ferramentas serem criadas.
Desde a PEP-427 (2012) o formato padrão dos binários é o `wheel`. Isso faz com que todos os
pacotes distribuídos sejam únicos.
O sistema de builds agora é dividido em duas partes:
● Backend
● Frontend
O Backend
O backend é responsável por compilar um pacote para distribuição em
sdist e bdist.
Para fazer isso as ferramentas de backend devem implementar algumas
chamadas (hooks / funções) obrigatórias:
● build_wheel: Função que cria o pacote binário especificado na
PEP-427
● build_sdist: Função que faz a compactação da biblioteca em um `tar`
> Existem outros opcionais, mas acredito que a leitura da PEP-517 pode aprofundar mais. A
PEP-660 (2021) expande novos hooks opcionais para que os wheels sejam editáveis.
Backend
O sistema de builds deve implementar um módulo com os hooks, esse
hooks devem ser implementados na chave build-backend. Algo como:
Backends buildando backends
Um problema comum ao criar um backend é que para que seu build seja
feito, ele precisa conseguir chamar a si mesmo. Para isso foi criada uma
nova chave na tabela backend-path. Para especificar onde o módulo que
contém os hooks estão:
Frontends
O frontend é responsável por configurar o ambiente de build do pacote.
Não é exigido nenhum ambiente em específico, a recomendação é que se
use o virtualenv. Aí ideia é que o hooks sejam chamados em
subprocessos (subprocess) e que os pacotes sejam pelo backend.
Fontend
Subprocesso
build-backend
Frontends
Várias ferramentas podem agir como frontend e o objetivo é que sejam
agnósticas nas chamadas. Pois os backends devem seguir a
especificação.
Duas ferramentas em particular são importantes nesse contexto. O build,
criado pelo PyPA para ser uma ferramenta genérica para o `[Link]`
e o pip.
Relação entre back e front
● Poetry (front) -> Poetry code [masonry] (back)
● Build (front) -> setuptools (back)
● Hatch (front) -> Hatcling (back)
● pip (front)
● rye (front)
● …
O objetivo final é que qualquer front consiga chamar qualquer back!
Futu
ro? Nem tudo está
pronto!
Algumas coisas faltando
Embora tenhamos andado um bastante pelo sistema de builds e
instalação de pacotes, ainda existem pontos em aberto:
1. Pip instalar as dependências sem chamar o backend
a. [Link]
2. Criar instalações deterministicas (como requirements)
a. PEP-665 (rejeitada)
b. PEP ainda sem número
i. [Link]
[Link]/livedepython [Link]@[Link] [Link]/dunossauro
Ajude o projeto <3