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.
