1.. _extending-distutils:
2
3*******************
4Extending Distutils
5*******************
6
7.. include:: ./_setuptools_disclaimer.rst
8
9Distutils can be extended in various ways.  Most extensions take the form of new
10commands or replacements for existing commands.  New commands may be written to
11support new types of platform-specific packaging, for example, while
12replacements for existing commands may be made to modify details of how the
13command operates on a package.
14
15Most extensions of the distutils are made within :file:`setup.py` scripts that
16want to modify existing commands; many simply add a few file extensions that
17should be copied into packages in addition to :file:`.py` files as a
18convenience.
19
20Most distutils command implementations are subclasses of the
21:class:`distutils.cmd.Command` class.  New commands may directly inherit from
22:class:`Command`, while replacements often derive from :class:`Command`
23indirectly, directly subclassing the command they are replacing.  Commands are
24required to derive from :class:`Command`.
25
26.. % \section{Extending existing commands}
27.. % \label{extend-existing}
28
29.. % \section{Writing new commands}
30.. % \label{new-commands}
31.. % \XXX{Would an uninstall command be a good example here?}
32
33
34Integrating new commands
35========================
36
37There are different ways to integrate new command implementations into
38distutils.  The most difficult is to lobby for the inclusion of the new features
39in distutils itself, and wait for (and require) a version of Python that
40provides that support.  This is really hard for many reasons.
41
42The most common, and possibly the most reasonable for most needs, is to include
43the new implementations with your :file:`setup.py` script, and cause the
44:func:`distutils.core.setup` function use them::
45
46   from distutils.command.build_py import build_py as _build_py
47   from distutils.core import setup
48
49   class build_py(_build_py):
50       """Specialized Python source builder."""
51
52       # implement whatever needs to be different...
53
54   setup(cmdclass={'build_py': build_py},
55         ...)
56
57This approach is most valuable if the new implementations must be used to use a
58particular package, as everyone interested in the package will need to have the
59new command implementation.
60
61Beginning with Python 2.4, a third option is available, intended to allow new
62commands to be added which can support existing :file:`setup.py` scripts without
63requiring modifications to the Python installation.  This is expected to allow
64third-party extensions to provide support for additional packaging systems, but
65the commands can be used for anything distutils commands can be used for.  A new
66configuration option, ``command_packages`` (command-line option
67:option:`!--command-packages`), can be used to specify additional packages to be
68searched for modules implementing commands.  Like all distutils options, this
69can be specified on the command line or in a configuration file.  This option
70can only be set in the ``[global]`` section of a configuration file, or before
71any commands on the command line.  If set in a configuration file, it can be
72overridden from the command line; setting it to an empty string on the command
73line causes the default to be used.  This should never be set in a configuration
74file provided with a package.
75
76This new option can be used to add any number of packages to the list of
77packages searched for command implementations; multiple package names should be
78separated by commas.  When not specified, the search is only performed in the
79:mod:`distutils.command` package.  When :file:`setup.py` is run with the option
80``--command-packages distcmds,buildcmds``, however, the packages
81:mod:`distutils.command`, :mod:`distcmds`, and :mod:`buildcmds` will be searched
82in that order.  New commands are expected to be implemented in modules of the
83same name as the command by classes sharing the same name.  Given the example
84command line option above, the command :command:`bdist_openpkg` could be
85implemented by the class :class:`distcmds.bdist_openpkg.bdist_openpkg` or
86:class:`buildcmds.bdist_openpkg.bdist_openpkg`.
87
88
89Adding new distribution types
90=============================
91
92Commands that create distributions (files in the :file:`dist/` directory) need
93to add ``(command, filename)`` pairs to ``self.distribution.dist_files`` so that
94:command:`upload` can upload it to PyPI.  The *filename* in the pair contains no
95path information, only the name of the file itself.  In dry-run mode, pairs
96should still be added to represent what would have been created.
97
98
99