# 7. Estendendo 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.

Distutils podem ser estendidos de várias maneiras. A maioria das extensões assume a forma de novos comandos ou substituições de comandos existentes. Novos comandos podem ser gravados para dar suporte a novos tipos de pacotes específicos da plataforma, por exemplo, enquanto substituições de comandos existentes podem ser feitas para modificar detalhes de como o comando opera em um pacote.

A maioria das extensões dos distutils é feita dentro de scripts `setup.py` que desejam modificar comandos existentes; muitos simplesmente adicionam algumas extensões de arquivo que devem ser copiadas em pacotes, além de `.py` como uma conveniência.

A maioria das implementações de comando distutils são subclasses da classe `distutils.cmd.Command`. Novos comandos podem herdar diretamente de `Command`, enquanto substituições geralmente derivam de `Command` indiretamente, criando subclasses diretamente do comando que eles estão substituindo. Os comandos são necessários para derivar de `Command`.

## 7.1. Integrando novos comandos

Existem diferentes maneiras de integrar novas implementações de comando nos distutils. O mais difícil é fazer lobby para a inclusão dos novos recursos no próprio distutils e aguardar (e exigir) uma versão do Python que forneça esse suporte. Isso é realmente difícil por vários motivos.

O mais comum, e possivelmente o mais razoável para a maioria das necessidades, é incluir as novas implementações com o script `setup.py` e fazer com que a função `distutils.core.setup()` use-as:

    from distutils.command.build_py import build_py as _build_py
    from distutils.core import setup

    class build_py(_build_py):
        """Specialized Python source builder."""

        # implement whatever needs to be different...

    setup(cmdclass={'build_py': build_py},
          ...)

Essa abordagem é mais valiosa se as novas implementações precisarem ser usadas para usar um pacote específico, pois todos os interessados no pacote precisarão ter a nova implementação de comando.

A partir do Python 2.4, uma terceira opção está disponível, destinada a permitir que novos comandos sejam adicionados, os quais podem ter suporte a scripts `setup.py` existentes sem exigir modificações na instalação do Python. Espera-se que isso permita que extensões de terceiros forneçam suporte a sistemas de empacotamento adicionais, mas os comandos podem ser usados para qualquer coisa em que os comandos distutils possam ser usados. Uma nova opção de configuração, `command_packages` (opção da linha de comando `--command-packages`), pode ser usada para especificar pacotes adicionais a serem pesquisados por módulos que implementam comandos. Como todas as opções do distutils, isso pode ser especificado na linha de comando ou em um arquivo de configuração. Esta opção só pode ser definida na seção `[global]` de um arquivo de configuração ou antes de qualquer comando na linha de comando. Se definido em um arquivo de configuração, ele poderá ser substituído na linha de comando; defini-lo como uma string vazia na linha de comando faz com que o padrão seja usado. Isso nunca deve ser definido em um arquivo de configuração fornecido com um pacote.

Esta nova opção pode ser usada para adicionar qualquer número de pacotes à lista de pacotes pesquisados para implementações de comandos; vários nomes de pacotes devem ser separados por vírgulas. Quando não especificada, a pesquisa é realizada apenas no pacote `distutils.command`. Quando `setup.py` é executado com a opção `--command-packages distcmds,buildcmds`, no entanto, os pacotes `distutils.command`, `distcmds` e `buildcmds` será pesquisado nessa ordem. Espera-se que novos comandos sejam implementados em módulos com o mesmo nome que o comando por classes que compartilham o mesmo nome. Dada a opção de linha de comando de exemplo acima, o comando bdist_openpkg pode ser implementado pela classe `distcmds.bdist_openpkg.bdist_openpkg` ou `buildcmds.bdist_openpkg.bdist_openpkg`.

## 7.2. Adicionando novos tipos de distribuição

Os comandos que criam distribuições (arquivos no diretório `dist/`) precisam adicionar pares `(command, filename)` ao `self.distribution.dist_files` para que upload possa ser carregado para o PyPI. O nome do arquivo no par não contém informações de caminho, apenas o nome do próprio arquivo. No modo de execução a seco, os pares ainda devem ser adicionados para representar o que teria sido criado.