Differences between revisions 11 and 12
Revision 11 as of 2015-09-11 18:52:06
Size: 16329
Editor: KaiNoda
Revision 12 as of 2016-12-12 21:14:41
Size: 16332
Editor: ?GeertStappers
Comment: added '{{{' to 'pycentral}}}'
Deletions are marked like this. Additions are marked like this.
Line 133: Line 133:
 * {{{celementtree}}} (extension with {{{egg}}}, CDBS using pycentral}}})  * {{{celementtree}}} (extension with {{{egg}}}, CDBS using {{{pycentral}}})

The debian-python team has adopted a policy for Python packages: http://www.debian.org/doc/packaging-manuals/python-policy/

The policy defines main principles that are shared by many people. However, it's implemented by a few different tools. dh_python2 is the new standard, and python-central and python-support are the common but deprecated ways. But there may still be no consensus which one is the best (though Python/FAQ contains some hints). We have done our best to make it easy to switch from one to the other and their usage is very similar from the maintainer's point of view. Either tool should support any package; maintainers should choose the tool with the interface that they prefer.


The following information might not be accurate anymore, have a look at Python Policy. See the link at the top of the page.

Vocabulary used in this page:

  • python extension: a .so file for use by python applications

  • python module: a .py file for use by python applications

  • public extension/module: an extension or module available in the default Python search path (sys.path) (ex: /usr/lib/python2.X/site-packages/)

  • private extension/module: an extension or module which is installed in a directory that is not in the default Python search path.

Updating your packages

All packages providing python modules/extensions (whether public or private) or python applications should:

  1. If the package used to build pythonX.Y-foo binary packages, you need to drop them and install the files in python-foo instead. Don't forget to add Replaces/Conflicts: pythonX.Y-foo (<< version) and Provides: ${python:Provides} in the python-foo binary package.

  2. Ensure that there's a ${python:Depends} in the Depends field

  3. Add an "XB-Python-Version: ${python:Versions}" field to each binary package in the debian/control file ("XB-" is not a variable, its literal, it is needed so dpkg-gencontrol will know that it's a unusual field and that it should keep it)

    • This seems outdated. Please check the Python Policy linked on top of the page for details.
  4. If your package provides public extensions:
    • You will have to Build-Depend on python-all-dev (>= 2.3.5-11) to have all the pythonX.Y-dev available during compilation.

    • You must adapt your debian/rules file to compile those extensions for all supported python versions. The set of python versions to use can be obtained with pyversions -r.

    • NOTE: The versioned dependency on python-all-dev is here to make sure that we have the right version of the pyversions script (the script itself is in the python package).

    • If needed, you can add a Provides: ${python:Provides} to your packages.

      • This is not recommended in the general case; you should only do that if another package needs this module and uses a specific Python version.
      • If you do so, you should also depend on the relevant pythonX.Y-bar for all modules that your package depends on, otherwise the Provides: is incorrect.

  5. If your package provides modules (either public or privates), you should use python-support or python-central to bytecompile them at installation time. Choose one of them and follow the specific instructions below.

Using python-central

  1. Build-Depends on debhelper (>= 5.0.38).

  2. Add a Build-Depends on python-central (>= 0.5.6).

  3. Add a dh_pycentral call instead of dh_python in debian/rules. If the package contains private modules/extensions, you must indicate the directories where they are installed as parameters to dh_pycentral.

  4. Add an XS-Python-Version field to debian/control (in the source stanza) with the value

    • all for public modules and public extensions (if the module/extension doesn't support all versions, use a more specific expression like >= 2.4 or >= 2.2, << 2.4)

    • current for packages with private modules or private extensions compiled for the current python version and for applications using /usr/bin/python. If the module or extension doesn't work with all Python version, one may specify something like current, >= 2.4 or even current, >= 2.2, << 2.5. If a shared extension is just built for the current python version, current is appropriate as well, but makes transitions more painful.

    • X.Y for applications using a non-standard Python version (they are using /usr/bin/pythonX.Y)

  5. If the public modules installed differ between python versions and if they can't be shared, you should set the following environment variable when invoking dh_pycentral.

# At the top of debian/rules
export DH_PYCENTRAL=nomove

See http://python-modules.alioth.debian.org/python-central_howto.txt for a more verbose description; examples for source packages using python-central are pyenchant, python-imaging (modules and extensions), pyparallel (modules only).

Using python-support

  1. Add a Build-Depends (or Build-Depends-Indep if the package is arch: all) on python-support (>= 0.5.3).

  2. Add a dh_pysupport call instead of dh_python in debian/rules. You must give the list of directories containing private modules as parameter to dh_pysupport (if they are outside standard package directories like /usr/share/$package).

  3. If your package doesn't support all python versions, you have to tell which versions are supported. For that you should create debian/pyversions. That file contains a comma separated list of versions or range of versions:

    • 2.2-2.4 means all versions between 2.2 and 2.4.

    • 2.3- means version 2.3 and any higher version

    • -2.5 means version 2.5 and any lower version

    • 2.1,2.4-2.5 means versions 2.1 and all versions between 2.4 and 2.5.

Note: if there's no debian/pyversions, dh_pysupport will try to use the XS-Python-Version field to find out the list of supported versions.

Another note: if there is a debian/pycompat file, you must launch dh_python after dh_pysupport, but the recommended way is to remove that file.

See /usr/share/doc/python-support/README.gz for a more complete description of how python-support works and how to use it (you may also want to read the latest doc from SVN).

Notes for CDBS users


  1. You need cdbs in your Build-Depends.

  2. You must edit debian/control like discussed in the first section.

Both above can be handled by having a debian/control.in file with @CDBS@ in Build-Depends, and regenerate debian/control by calling debian/rules clean DEB_MAINTAINER_MODE=1.

CDBS + distutils

Here's how your debian/rules could look like when using CDBS with distutils:

include /usr/share/cdbs/1/class/python-distutils.mk
include /usr/share/cdbs/1/rules/debhelper.mk

# If your package provides eggs, install egg-info directories instead of real eggs
# DEB_PYTHON_INSTALL_ARGS_ALL += --single-version-externally-managed

CDBS + autotools

Here's how your debian/rules could look like when using CDBS with python-enabled autotools:

include /usr/share/cdbs/1/class/python-autotools.mk
include /usr/share/cdbs/1/rules/debhelper.mk

CDBS the hard way

If your package does not uses distutils or autotools, then you have to call dh_python and dh_pysupport manually. the correct hook is {binary-install/$(package)}::

Here's how your makefile could look like:

include /usr/share/cdbs/1/class/autoconf.mk
include /usr/share/cdbs/1/rules/debhelper.mk

        dh_pysupport -pfoo

Or if you're a make maniac:

# packages to operate on must be overridden before including CDBS
MY_PACKAGES_WITH_PYTHON = foo-pkg python-bar

include /usr/share/cdbs/1/class/autoconf.mk
include /usr/share/cdbs/1/rules/debhelper.mk

$(patsubst %,binary-install/%,$(MY_PACKAGES_WITH_PYTHON)) ::
        dh_pysupport -p$(cdbs_curpkg)


NOTE: Many examples date back from the very early days of the transition and do not respect all the points above (version of build-dependencies, invocation of pyversions). Do not copy blindly.

For python modules

Examples at http://people.debian.org/~hertzog/python/examples/ :

  • kid (module with egg, CDBS with python-support)

For python extensions

Examples at http://people.debian.org/~hertzog/python/examples/ :

  • python-pam (extension only, debhelper)

  • pyenchant (extension with modules and egg, debhelper using pycentral)

  • celementtree (extension with egg, CDBS using pycentral)

  • libgpod (python bindings of a C library, hand-written makefile)

  • python-orbit (extension built via autoconf)

Adapting the rules files using shell:

PYDEF=$(shell pyversions -d)
PYVERS=$(shell pyversions -r)
build: build-stamp
        set -e; \
        for python in $(PYVERS); do \
                python=$$(echo $$python | sed "s/$(PYDEF)/python/"); \
                $$python setup.py build; \
        touch build-stamp

        for python in $(PYVERS); do \
                python=$$(echo $$python | sed "s/$(PYDEF)/python/"); \
                $$python setup.py clean; \
        rm -rf build-stamp build

install: build
        dh_clean -k

        set -e; \
        for python in $(PYVERS); do \
                python=$$(echo $$python | sed "s/$(PYDEF)/python/"); \
                $$python setup.py install --root=debian/python-foo; \
# Build architecture-dependent files here.
binary-arch: build install

Using makefile trickery:

PYDEF=$(shell pyversions -d)
PYVERS=$(shell pyversions -r)
build: build-stamp
build-stamp: $(PYVERS:%=build-ext-%)
        touch $@
        $(subst $(PYDEF),python,$*) setup.py build
        touch $@
install: install-stamp
install-stamp: build-stamp $(PYVERS:%=install-ext-%)
        $(subst $(PYDEF),python,$*) setup.py install --root $(CURDIR)/debian/python-foo

Notes for packages with private modules/extensions

Not many changes are needed. Moving the packages to the new policy will allow automatic byte compilation on upgrades of the default python version. The location of the private modules does not have to change; if your package installs files in /usr/lib/site-python, please consider moving these to /usr/lib/pythonX.Y/site-packages and using python-central/python-support for handling these.

Packages with private modules/extensions should have an XS-Python-Version: current attribute (or: current, >= 2.4, if the packages doesn't work with older python versions), and an attribute XB-Python-Version: ${python:Versions}, which will be expanded by dh_python to either current, or to the specific version, if the package contains an extension module).

Packages using python-central

  • debian/control:

    • The addition of the XS-Python-Version/XB-Python-Version fields is required.

    • Build dependency on python-central (>= 0.6) is required.

    • Dependency on ${python:Depends} should be added

  • debian/rules: dh_pycentral must be called instead of dh_python

  • The location of the private modules is determined automatically by pycentral.

See above for more details.

Packages using python-support

  • debian/control:

    • The addition of the XS-Python-Version/XB-Python-Version fields is appreciated.

    • Build dependency on python-support (>= 0.5.3) is required.

    • Dependency on ${python:Depends} should be added

  • debian/rules: dh_pysupport must be called instead of dh_python with the path to the private modules as parameters.

Packages not using python-central/python-support

debian/control: The addition of the XS-Python-Version/XB-Python-Version fields is appreciated.

The package must include a script /usr/share/python/runtime.d/<package>.rtupdate. That script is called three times, with three arguments: <command> <old runtime> <new runtime> (i.e. <command> python2.3 python2.4):

  1. it's called with pre-rtupdate <old> <new> before anything changes in the python runtime.

  2. it's called with rtupdate <old> <new>, which triggers the runtime update, and the byte compilation, usually, only python-support and python-central need to react here, and during that call the python runtime may be in a quite loosy shape.

  3. it's called then with post-rtupdate <old> <new> after the byte compilation.

If you do custom, byte-compilation of your private modules. It should honor /etc/python/debian_config, if the package allows calling the python interpreter with the -O option.

Notes for packages with an embedded python interpreter

If the package contains additional modules (private or shared), the above for the packaging guidelines. If it's just the embedded interpreter, please add the XS-Python-Version/XB-Python-Version fields, so that the package can be identified for binNMUing if the default python version changes.

Shared installation area for Python modules

Originally proposed in http://lists.debian.org/debian-python/2006/06/msg00184.html. Packaging tools (python-central up to version 0.5.50) did install shared python modules into tool- and package-specific directories, disabling conflict and replaces checkings by dpkg. To delegate this checking again to dpkg, shared python modules managed by python-central are installed into a common area.

  • /usr/share/pyshared: Every file into this directory is made available in /usr/lib/pythonX.Y/site-packages, if the package supports pythonX.Y and pythonX.Y is installed on the system. This directory is not directly included in sys.path.

  • /usr/share/pyshared-data: This directory holds meta information in a file <package name> for every package which installs files into /usr/share/pyshared. The format of this file must be read by the SafeConfigParser class (with optionxform set to str), format documented in http://docs.python.org/lib/module-ConfigParser.html. It must have a section python-package, and in this section an attribute format. It should have an attribute python-version replicating the Python-Version attribute from the binary package. A format value of 1 means, that two more sections are present in the meta file:

    • A tool specifc section (pycentral for packages managed by python-central.

    • A section files listing files managed by the tool, in the form <absolute file name>=d|f (directory/file).


format = 1
python-version = current
version = 0.6.1

CategoryPermalink CategoryPackaging