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.

Recipes

The following information might not be accurate anymore, have a look at Python Policy instead

Vocabulary used in this page:

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)
  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

CDBS + distutils

Here are some guidelines to help you update your packages if you're using CDBS with python-distutils.mk:

  1. You need cdbs (>= 0.4.49) in your Build-Depends.

  2. You will have to set DEB_PYTHON_SYSTEM to "pycentral" or "pysupport" before the CDBS include directives.
  3. You must edit debian/control like discussed in the first section. Possibly you want to edit debian/control.in and regenerate your debian/control by calling "DEB_AUTO_UPDATE_DEBIAN_CONTROL=1 debian/rules clean" (beware if there's no DEB_PYTHON_SYSTEM it won't generate the expected build dependencies), and then manually cleaning/fixing the Build-Depends field (see 373653).

  4. Note that debhelper.mk must be included before python-distutils.mk so that dh_pysupport/dh_pycentral and dh_python are actually called.
  5. If you are using dpatch to create the setup.py for distutils, you should include distutils.mk before dpatch.mk so that the clean target will clean properly and not throw an error for not finding the setup.py file.

Here's how your debian/rules could look like:

# DEB_PYTHON_SYSTEM=pycentral
DEB_PYTHON_SYSTEM=pysupport

# Debhelper must be included before python-distutils to use
# dh_python / dh_pycentral / dh_pysupport
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/python-distutils.mk
include /usr/share/cdbs/1/rules/simple-patchsys.mk

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

CDBS + the hard way

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

  1. You need cdbs (>= 0.4.49) in your Build-Depends.

  2. You must edit debian/control like discussed in the first section. Possibly you want to edit debian/control.in and regenerate your debian/control by calling "DEB_AUTO_UPDATE_DEBIAN_CONTROL=1 debian/rules clean" (beware if there's no DEB_PYTHON_SYSTEM it won't generate the expected build dependencies), and then manually cleaning/fixing the Build-Depends field (see 373653).

Here's how your makefile could look like:

include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/rules/simple-patchsys.mk
include /usr/share/cdbs/1/class/autoconf.mk
include /usr/share/cdbs/1/rules/utils.mk


binary-install/foo::
        dh_pysupport -pfoo

Or if you're a make maniac:

include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/rules/simple-patchsys.mk
include /usr/share/cdbs/1/class/autoconf.mk
include /usr/share/cdbs/1/rules/utils.mk

MY_PACKAGES_WITH_PYTHON := foo-pkg python-bar

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

Examples

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/ :

For python extensions

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

Adapting the rules files using shell:

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

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

install: build
        dh_testdir
        dh_testroot
        dh_clean -k
        dh_installdirs

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

Using makefile trickery:

PYDEF=$(shell pyversions -d)
PYVERS=$(shell pyversions -r)
[...]
build: build-stamp
build-stamp: $(PYVERS:%=build-ext-%)
        touch $@
build-ext-%:
        dh_testdir
        $(subst $(PYDEF),python,$*) setup.py build
        touch $@
[...]
install: install-stamp
install-stamp: build-stamp $(PYVERS:%=install-ext-%)
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

See above for more details.

Packages using python-support

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.

Example:

[python-package]
format = 1
python-version = current
[pycentral]
version = 0.6.1
[files]
/usr/share/pyshared/AptUrl=d
/usr/share/pyshared/AptUrl/Parser.py=f
/usr/share/pyshared/AptUrl/__init__.py=f
/usr/share/pyshared/AptUrl/Version.py=f
/usr/share/pyshared/apturl-0.2.2.egg-info=f


CategoryPermalink CategoryPackaging