| .. _extending-distutils: |
| |
| ******************* |
| Extending Distutils |
| ******************* |
| |
| Distutils can be extended in various ways. Most extensions take the form of new |
| commands or replacements for existing commands. New commands may be written to |
| support new types of platform-specific packaging, for example, while |
| replacements for existing commands may be made to modify details of how the |
| command operates on a package. |
| |
| Most extensions of the distutils are made within :file:`setup.py` scripts that |
| want to modify existing commands; many simply add a few file extensions that |
| should be copied into packages in addition to :file:`.py` files as a |
| convenience. |
| |
| Most distutils command implementations are subclasses of the |
| :class:`distutils.cmd.Command` class. New commands may directly inherit from |
| :class:`Command`, while replacements often derive from :class:`Command` |
| indirectly, directly subclassing the command they are replacing. Commands are |
| required to derive from :class:`Command`. |
| |
| .. % \section{Extending existing commands} |
| .. % \label{extend-existing} |
| |
| .. % \section{Writing new commands} |
| .. % \label{new-commands} |
| .. % \XXX{Would an uninstall command be a good example here?} |
| |
| |
| Integrating new commands |
| ======================== |
| |
| There are different ways to integrate new command implementations into |
| distutils. The most difficult is to lobby for the inclusion of the new features |
| in distutils itself, and wait for (and require) a version of Python that |
| provides that support. This is really hard for many reasons. |
| |
| The most common, and possibly the most reasonable for most needs, is to include |
| the new implementations with your :file:`setup.py` script, and cause the |
| :func:`distutils.core.setup` function use them:: |
| |
| 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}, |
| ...) |
| |
| This approach is most valuable if the new implementations must be used to use a |
| particular package, as everyone interested in the package will need to have the |
| new command implementation. |
| |
| Beginning with Python 2.4, a third option is available, intended to allow new |
| commands to be added which can support existing :file:`setup.py` scripts without |
| requiring modifications to the Python installation. This is expected to allow |
| third-party extensions to provide support for additional packaging systems, but |
| the commands can be used for anything distutils commands can be used for. A new |
| configuration option, :option:`command_packages` (command-line option |
| :option:`--command-packages`), can be used to specify additional packages to be |
| searched for modules implementing commands. Like all distutils options, this |
| can be specified on the command line or in a configuration file. This option |
| can only be set in the ``[global]`` section of a configuration file, or before |
| any commands on the command line. If set in a configuration file, it can be |
| overridden from the command line; setting it to an empty string on the command |
| line causes the default to be used. This should never be set in a configuration |
| file provided with a package. |
| |
| This new option can be used to add any number of packages to the list of |
| packages searched for command implementations; multiple package names should be |
| separated by commas. When not specified, the search is only performed in the |
| :mod:`distutils.command` package. When :file:`setup.py` is run with the option |
| :option:`--command-packages` :option:`distcmds,buildcmds`, however, the packages |
| :mod:`distutils.command`, :mod:`distcmds`, and :mod:`buildcmds` will be searched |
| in that order. New commands are expected to be implemented in modules of the |
| same name as the command by classes sharing the same name. Given the example |
| command line option above, the command :command:`bdist_openpkg` could be |
| implemented by the class :class:`distcmds.bdist_openpkg.bdist_openpkg` or |
| :class:`buildcmds.bdist_openpkg.bdist_openpkg`. |
| |
| |
| Adding new distribution types |
| ============================= |
| |
| Commands that create distributions (files in the :file:`dist/` directory) need |
| to add ``(command, filename)`` pairs to ``self.distribution.dist_files`` so that |
| :command:`upload` can upload it to PyPI. The *filename* in the pair contains no |
| path information, only the name of the file itself. In dry-run mode, pairs |
| should still be added to represent what would have been created. |
| |
| |