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