# 1. Uma Introdução ao Distutils

Nota

Este documento está sendo mantido apenas até que a documentação do `setuptools` em https://setuptools.readthedocs.io/en/latest/setuptools.html cubra independentemente todas as informações relevantes atualmente incluídas aqui.

Este documento trata do uso do Distutils tornando possível a distribuição dos seus módulos Python, podendo assim, concentrar-se no seu papel de desenvolvedor/distribuidor: caso estejas procurando informações sobre a instalação de módulos Python, deverás consultar o capítulo Instalando módulos Python (versão legada).

## 1.1. Conceitos & Terminologias

Utilizar o Distutils é bastante simples, tanto para desenvolvedores de módulos quanto para usuários/administradores que instalam módulos de terceiros. Como desenvolvedor, suas responsabilidades (além de escrever um código sólido, bem documentado e bem testado, é claro!) são:

- escrever um script setup (`setup.py` através da conversão)

- (opcional) escrever um arquivo Setup de configuração

- criar uma distribuição de fontes

- (opcional) criar uma ou mais distribuições compiladas (binárias)

Cada uma dessas tarefas são tratadas neste documento.

Nem todos os desenvolvedores de módulos têm acesso a uma infinidade de plataformas, portanto, nem sempre é possível esperar que eles criem uma infinidade de distribuições construídas. Espera-se que uma classe de intermediários, chamada empacotadores, surja para atender a essa necessidade. Os empacotadores pegam as distribuições fonte lançadas pelos desenvolvedores do módulo, as compilam em uma ou mais plataformas e lançam as distribuições compiladas resultantes. Assim, os usuários das plataformas mais populares poderão instalar as distribuições mais populares de módulos Python da maneira mais natural possível para sua plataforma, sem precisar executar um único script de configuração ou compilar uma linha de código.

## 1.2. Um Exemplo Simples

O script de configuração geralmente é bastante simples, embora, como esteja escrito em Python, não haja limites arbitrários para o que você pode fazer com ele, mas você deve ter cuidado ao colocar operações arbitrariamente caras em seu script de configuração. Ao contrário, digamos, dos scripts de configuração no estilo Autoconf, o script de instalação pode ser executado várias vezes no decorrer da compilação e instalação da distribuição do módulo.

Se tudo o que você quer fazer é distribuir um módulo chamado `foo`, contido em um arquivo `foo.py`, então seu script de instalação pode ser tão simples quanto este:

    from distutils.core import setup
    setup(name='foo',
          version='1.0',
          py_modules=['foo'],
          )

Algumas observações:

- a maioria das informações que você fornecerá ao Distutils será fornecida como argumentos nomeados para a função `setup()`

- esses argumentos nomeados se enquadram em duas categorias: metadados do pacote (nome, número da versão) e informações sobre o conteúdo do pacote (uma lista de módulos Python puros, neste caso)

- módulos são especificados pelo nome do módulo, não pelo nome do arquivo (o mesmo se aplica aos pacotes e extensões)

- é recomendável que você forneça um pouco mais de metadados, em particular seu nome, endereço de e-mail e uma URL para o projeto (consulte a seção Escrevendo o Script de Configuração por exemplo)

Para criar uma distribuição fonte para este módulo, você deve criar um script de instalação, `setup.py`, contendo o código acima, e executar este comando a partir de um terminal:

    python setup.py sdist

No Windows, abra uma janela do prompt de comando (Iniciar ‣ Acessórios) e altere o comando para:

    setup.py sdist

sdist criará um arquivo (por exemplo, tarball no Unix, arquivo ZIP no Windows) contendo seu script de instalação `setup.py` e seu módulo `foo.py`. O arquivo será nomeado `foo-1.0.tar.gz` (ou `.zip`) e será descompactado em um diretório `foo-1.0`.

Se um usuário final deseja instalar o seu módulo `foo`, tudo o que eles precisam fazer é baixar `foo-1.0.tar.gz` (ou `.zip`), descompactá-lo, e — no diretório `foo-1.0` — executar:

    python setup.py install

que finalmente copiará `foo.py` para o diretório apropriado para módulos de terceiros em sua instalação do Python.

Este exemplo simples demonstra alguns conceitos fundamentais dos Distutils. Primeiro, desenvolvedores e instaladores têm a mesma interface de usuário básica, ou seja, o script de instalação. A diferença é que comandos do Distutils eles usam: o comando sdist é quase exclusivamente para desenvolvedores de módulos, enquanto install é mais frequentemente para instaladores (embora a maioria dos desenvolvedores deseje instalar ocasionalmente seu próprio código).

Outros formatos de distribuição úteis úteis são o RPM, implementado pelo comando bdist_rpm, pkgtool do Solaris (bdist_pkgtool) e swinstall do HP-UX (bdist_sdux). Por exemplo, o seguinte comando criará um arquivo RPM chamado `foo-1.0.noarch.rpm`:

    python setup.py bdist_rpm

(O comando bdist_rpm usa o executável rpm, portanto, ele deve ser executado em um sistema baseado em RPM, como Red Hat Linux, SuSE Linux ou Mandrake Linux.)

Você pode descobrir quais formatos de distribuição estão disponíveis a qualquer momento executando:

    python setup.py bdist --help-formats

## 1.3. Terminologia geral do Python

Se você está lendo este documento, provavelmente tem uma boa ideia do que são módulos, extensões e assim por diante. No entanto, apenas para ter certeza de que todos estão operando de um ponto de partida comum, oferecemos o seguinte glossário de termos comuns do Python:

módulo

  a unidade básica de reutilização de código em Python: um bloco de código importado por algum outro código. Três tipos de módulos nos importam aqui: módulos Python puros, módulos de extensão e pacotes.

pure Python module (módulo Python puro)

  um módulo escrito em Python e contido em um único arquivo `.py` (e possivelmente arquivos `.pyc` associados). Às vezes referido como um “módulo puro”.

módulo de extensão

  um módulo escrito na linguagem de baixo nível da implementação Python: C/C++ para Python, Java para Jython. Normalmente contido em um único arquivo pré-compilado carregável dinamicamente, por exemplo, um arquivo de objeto compartilhado (`.so`) para extensões Python no Unix, uma DLL (dada a extensão `.pyd`) para extensões Python no Windows ou um arquivo de classe Java para extensões Jython. (Observe que, atualmente, o Distutils só lida com extensões C/C++ para Python.)

pacote

  um módulo que contém outros módulos; tipicamente contido em um diretório no sistema de arquivos e diferenciado de outros diretórios pela presença de um arquivo `__init__.py`.

root package (pacote raiz)

  a raiz da hierarquia de pacotes. (Este não é realmente um pacote, uma vez que não possui um arquivo `__init__.py`. Mas temos que chamá-lo de alguma coisa.) A grande maioria da biblioteca padrão está no pacote raiz, assim como muitos módulos pequenos e independentes de terceiros que não pertencem a uma coleção de módulos maior. Ao contrário dos pacotes regulares, os módulos no pacote raiz podem ser encontrados em muitos diretórios: na verdade, cada diretório listado em `sys.path` contribui com módulos para o pacote raiz.

## 1.4. Terminologia específica do Distutils

Os termos a seguir se aplicam mais especificamente ao domínio de distribuição de módulos Python usando Distutils:

module distribution (distribuição de módulo)

  uma coleção de módulos Python distribuídos juntos como um único recurso para download e devem ser instalados em massa. Exemplos de algumas distribuições de módulos bem conhecidas são NumPy, SciPy, Pillow ou mxBase. (Isso seria chamado de pacote, exceto que o termo já é usado no contexto Python: uma distribuição de módulo único pode conter zero, um ou muitos pacotes Python.)

pure module distribution (distribuição de módulo pura)

  uma distribuição de módulo que contém apenas módulos e pacotes Python puros. Às vezes chamada de “distribuição pura”.

non-pure module distribution (distribuição de módulo não pura)

  uma distribuição de módulo que contém pelo menos um módulo de extensão. Às vezes chamada de “distribuição não pura”.

distribution root (raiz da distribuição)

  o diretório de nível superior de sua árvore de fontes (ou distribuição fonte); o diretório onde existe `setup.py`. Geralmente, `setup.py` vai ser executado a partir deste diretório.