Estrutura e Layout de Pacotes Python#
Há dois layouts diferentes que você verá comumente dentro do ecossistema de packaging Python: os layouts src e flat. Ambos os layouts têm vantagens para diferentes grupos de mantenedores.
Sugerimos fortemente, mas não exigimos, que você use o layout src/ (discutido abaixo) para criar o seu pacote Python. Esse layout também é recomendado no tutorial do guia de packaging da PyPA.
O pyOpenSci nunca exigirá uma estrutura de pacote específica para a revisão por pares
Entendemos que seria necessário um esforço significativo para os mantenedores existentes migrarem para um novo layout.
A visão geral nesta página apresenta recomendações que consideramos as melhores para alguém que está começando com o packaging Python ou para alguém cujo pacote tem uma build simples e que pode estar aberto a migrar para uma abordagem mais à prova de falhas.
Outros recursos que você pode conferir:
Você pode usar ferramentas como o Hatch para criar rapidamente uma estrutura moderna de pacote Python. Confira o nosso tutorial de início rápido:
Quer aprender como criar a estrutura para construir o seu pacote? Clique aqui.
O que é o layout de código-fonte de um pacote Python?#
Abaixo está um exemplo da estrutura do layout src/package.
myPackageRepoName
├── CHANGELOG.md ┐
├── CODE_OF_CONDUCT.md │
├── CONTRIBUTING.md │
├── docs │ Package documentation
│ └── index.md
│ └── ... │
├── LICENSE │
├── README.md ┘
├── pyproject.toml ] Package metadata and build configuration
├── src ┐
│ └── myPackage │
│ ├── __init__.py │ Package source code
│ ├── moduleA.py │
│ └── moduleB.py ┘
└── tests ┐
└── ... ┘ Package tests
Observe a localização dos seguintes diretórios no exemplo acima:
docs/: Discutido no nosso capítulo sobre documentação, este diretório contém o site de documentação voltado para o usuário. Em um layout src/, o docs/ normalmente é incluído no mesmo nível de diretório que a pasta src/.
tests/ Este diretório contém os testes para o código do seu projeto. Em um layout src/, os testes normalmente são incluídos no mesmo nível de diretório que a pasta src/.
src/package/: este é o diretório que contém o código do seu projeto Python. «Package» normalmente é o nome do seu projeto.
Também no exemplo acima, observe que todos os arquivos de documentação principais que o pyOpenSci exige ficam na raiz do diretório do seu projeto. Esses arquivos incluem:
CHANGELOG.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
LICENSE.txt
README.md
Clique aqui para ler sobre os nossos requisitos de documentação de packaging.
O layout src e os testes#
O benefício de usar o layout src/package é que ele garante que os testes sejam executados contra a versão instalada do seu pacote, em vez dos arquivos no diretório de trabalho do seu pacote. Se você executar os seus testes nos seus arquivos em vez da versão instalada do seu pacote, você pode estar deixando passar problemas que os usuários encontram quando o seu pacote é instalado.
Se o tests/ estiver fora do diretório src/package, ele não será incluído na wheel do pacote. Isso deixa o tamanho do seu pacote ligeiramente menor, o que impõe um ônus de armazenamento menor ao PyPI e os torna mais rápidos de baixar.
Como o Python descobre e prioriza a importação de módulos
Por padrão, o Python adiciona um módulo do seu diretório de trabalho atual ao início do caminho de busca de módulos do Python.
Isso significa que, se você executar os seus testes no diretório de trabalho do seu pacote, usando um layout flat, /package/module.py, o Python descobrirá o arquivo package/module.py antes de descobrir o pacote instalado.
No entanto, se o seu pacote ficar em uma estrutura de diretório src/ src/package, então ele não será adicionado ao caminho do Python por padrão. Isso significa que, quando você importar o seu pacote, o Python será forçado a buscar no ambiente ativo (que tem o seu pacote instalado).
Nota: As versões 3.11 e superiores do Python têm uma configuração de caminho que pode ser ajustada para garantir que a prioridade seja usar primeiro os pacotes instalados (por exemplo, PYTHONSAFEPATH).
Não inclua os testes na wheel do seu pacote#
Escrever testes para o seu pacote é importante; no entanto, por padrão, não recomendamos incluir os testes como parte da wheel do seu pacote. Por outro lado, não incluir os testes na distribuição do seu pacote tornará mais difícil para outras pessoas, além de você, testar se o seu pacote roda corretamente no sistema delas. Se você tem um conjunto de testes pequeno (arquivos Python + dados) e acha que os seus usuários podem querer executar os testes localmente em seus sistemas, você pode incluir os testes movendo o diretório tests/ para dentro do diretório src/package (veja o exemplo abaixo).
src/
package/
tests/
docs/
Incluir o diretório tests/ no seu diretório src/package garante que os testes sejam incluídos na wheel do seu pacote.
Certifique-se de ler a documentação do pytest para saber mais sobre como incluir os testes na distribuição do seu pacote.
Desafios ao incluir testes e dados em uma wheel de pacote
Os testes, especialmente quando acompanhados de dados de teste, podem criar alguns pequenos desafios, incluindo:
Ocupar espaço na sua distribuição, que se acumulará com o tempo como espaço de armazenamento no PyPI
Arquivos de tamanho grande também podem deixar a instalação do pacote mais lenta.
No entanto, em alguns casos, particularmente no ecossistema científico do Python, você pode precisar incluir os testes.
Não inclua os conjuntos de dados do seu conjunto de testes no seu pacote#
Se você incluir os seus testes na distribuição do seu pacote, desencorajamos fortemente que você inclua dados no diretório do seu conjunto de testes. Em vez disso, hospede os seus dados de teste em um repositório como o Figshare ou o Zenodo. Use uma ferramenta como o Pooch para acessar os dados quando você (ou um usuário) executar os testes.
Para mais informações sobre testes de pacotes Python, veja a seção de testes do nosso guia.
O layout src/package é semanticamente mais claro. O código é sempre encontrado no diretório src/package, e o
tests/e odocs/ficam no diretório raiz.
Importante
Se os testes do seu pacote requerem dados, NÃO inclua esses dados dentro da estrutura do seu pacote. Incluir dados na estrutura do seu pacote aumenta o tamanho dos seus arquivos de distribuição. Isso impõe um ônus de manutenção a repositórios como o PyPI e o Anaconda.org, que precisam lidar com milhares de envios de pacotes.
Clique aqui para ver um tutorial de início rápido sobre como criar o seu pacote Python.
O que é o layout flat de pacote Python?#
Muitos pacotes científicos usam o flat-layout porque:
Esse layout é usado por muitos dos principais pacotes científicos em Python, como NumPy, SciPy e Matplotlib.
Muitas ferramentas Python dependem de ferramentas em outras linguagens e/ou de builds complexas com etapas de compilação. Muitos mantenedores preferem os recursos do layout flat para builds mais complexas.
Embora sugiramos que você use o layout src/package discutido acima, é importante entender também o layout flat, especialmente se você planeja contribuir com um pacote que usa esse layout.
Por que a maioria dos pacotes científicos em Python não usa o layout src/
Migrar pacotes científicos maiores que já usam um layout flat consumiria tempo e recursos significativos.
No entanto, as vantagens de usar o layout src/package para um iniciante são significativas. Por isso, recomendamos que você use o layout src/package se estiver criando um novo pacote.
Diversos pacotes no ecossistema tiveram que migrar para um layout src/package.
Como é a estrutura do layout flat?#
As principais características do layout flat são:
O código-fonte do seu pacote fica em um diretório com o nome do seu pacote na raiz do seu diretório
Frequentemente, o diretório
tests/também fica dentro desse mesmo diretóriopackage.
Abaixo você pode ver a estrutura recomendada de um pacote científico em Python usando o layout flat.
myPackage/
├── CHANGELOG.md ┐
├── CODE_OF_CONDUCT.md │
├── CONTRIBUTING.md │
├── docs/ │ Package documentation
│ └── ... │
├── LICENSE │
├── README.md ┘
├── pyproject.toml ] Package metadata and build configuration
| myPackage/ ┐
│ ├── __init__.py │ Package source code
│ ├── moduleA.py │
│ └── moduleB.py ┘
tests/ ┐
└── test-file1.py | Package tests
└── .... ┘
Benefícios de usar o layout flat no seu pacote Python#
Há alguns benefícios para a comunidade científica em usar o layout flat.
Essa estrutura tem sido historicamente usada em todo o ecossistema e é improvável que os pacotes que a utilizam mudem.
Você pode importar o pacote diretamente do diretório raiz. Para alguns, isso está enraizado em seus respectivos fluxos de trabalho. No entanto, para um iniciante, o perigo de fazer isso é que você não está desenvolvendo e testando contra a versão instalada do seu pacote. Em vez disso, você está trabalhando diretamente com os arquivos flat.
Principais pacotes científicos em Python que usam o layout flat
Seria um custo e um ônus de manutenção significativo migrar todos esses pacotes para um layout diferente. Os benefícios potenciais do layout de código-fonte para essas ferramentas não valem o investimento de manutenção.
Múltiplos pacotes em uma pasta src/
Em alguns casos mais avançados, você pode ter mais de um pacote no seu diretório src/. Veja o repositório do Black no GitHub para ver um exemplo disso. No entanto, para a maioria dos iniciantes, você provavelmente terá apenas um subdiretório na sua pasta src/.