From Fedora Project Wiki

Packagers would like to support both Fedora and EPEL releases with common specfiles wherever possible. Pretty much anything can be done using conditionals (%if/%endif) but this can be annoying and has a cost in specfile legibility. It would be nice if there was some alternative.

It is assumed up front that simply having Provides: python2-X added to the RHEL packages in question is not a possibility. While Red Hat may decide do some of this in RHEL7 point releases, there is very little chance that RHEL6 will change.

The current implementation

  • Each package without a python2-* provide gets a separate python2-X stub package. This is a separate git repository, not something generated from an EPEL branch of the regular repo.
  • They will carry the %version from the base RHEL package.
  • Release technically shouldn't matter as long as it's <= the release of the RHEL package. To avoid any potential issues if the RHEL package does grow the python2-* provide, it can never be greater.
    • Making the releases equal gives us no wiggle room in case we need to update the stub package for whatever reason.
    • Using 0 is technically a guidelines violation, but one that's easily justified.
    • In the case where RHEL packages a prerelease, we really need to start from 0 and move to something like 0.0.1. (docutils in EL7 has release 0.2.<date> so the plan has to allow a way to stay below that.)
  • The individual packages will carry no files at all, just a single versioned Requires: on the base package.
    • This should take the form Requires: python-X >= %version.
  • The stub package will also provide python2dist(foo), to match what Fedora provides automatically.

Since in RHEL it's possible for one package to have many different versions in various channels, it makes sense to try to stick with the lowest version that's in any channel. In any case, EPEL is limited in what channels it supports.

Maintenance needed

These packages must be immediately retired if an update to the base RHEL package starts providing python2-X. However, keeping the release at a lower value means that nothing will break if there's a delay; there will simply be a brief period where both EPEL and RHEL provide the same package, but the RHEL one is newer.

The version should be updated if the version of the base RHEL package changes, so that versioned dependencies work as expected. This can be scripted using and phg_el6.json and a small bit of code.

Why don't we....

  • Just stuff these all in a single source package, which can spit out a bunch of these stub packages without all of the hassle of maintaining everything separately?

Because then we'd have to bump the release of all of those generated packages when we just need to change one. Since we have to keep the release strictly lower, things get difficult.

  • Use an unversioned Requires: on the base package?

Because this could lead to a situation where a package requires python2-foo >= 3, which in turn requires any version of python-foo. If a host hasn't updated and so still has python-foo version 2 then the dependencies would all technically be satisfied but things wouldn't actually work.

  • Use a strict version dependency on the base package?

Because this could prevent RHEL upgrades if the RHEL package is updated but the EPEL package isn't.

  • Just use an EPEL branch of the existing package repository?

Because that would make the source package name python-X, which would really look like a duplication between base RHEL and EPEL. To avoid any possibility of confusion a new repository is needed.

  • Provide python2.7dist(foo)?

This could be done in EPEL7 if it would be useful to someone. (Just ask.) Of course EPEL6 doesn't have python2.7, and adding python2.6dist(foo) would provide no additional uniformity.

Open questions

Is there any situation where these packages will cause some problem for end users?

Packages already done

  • python2-dateutil (requires python-dateutil)
  • python2-dns (requires python-dns)
  • python2-doctils (requires python-docutils)
  • python2-enum34 (requires python-enum34) (EL7 only because python-enum34 is in EPEL6)
  • python2-httplib2 (requires python-httplib2)
  • python2-idna (requires python-idna) (EL7 only; python-idna does not exist in EL6)
  • python2-matplotlib (requires python-matplotlib)
  • python2-pytest (requires pytest)
  • python2-numpy (requires numpy)
  • python2-pyxdg (requires pyxdg) (EL6 only; not needed in EL7)
  • python2-pyyaml (requires PyYAML)
  • python2-requests (requires python-requests)
  • python2-setuptools (requires python-setuptools) (EL6 only; not needed in EL7)
  • python2-six (requires python2-six)
  • python2-sphinx (requires python-sphinx)
  • python2-zope-interface (requires python-zope-interface)

Packages in progress

(None at the moment.)

Packages to do next

Feel free to add some below. Before adding, please make sure that you are requesting a stub for a package that is in RHEL. If the package is in EPEL, then you should work with the EPEL maintainer to use the modern Python packaging guidelines. Please only request stubs for EPEL packages when the EPEL maintainer is unwilling to make the necessary changes.

  • python-requests-oauthlib (EL 7 only)

The skeleton spec

%global dummy setuptools

Name:       python2-%dummy
Version:    0.6.10
Release:    0%{?dist}
Summary:    Dummy package depending on python-%dummy
License:    Public Domain
Requires:   python-%dummy >= %version
Provides:   python2dist(%dummy) = %version
BuildArch:  noarch

This package exists only to allow packagers to uniformly depend on
python2-%dummy instead of conditionalizing those dependencies based on the
version of EPEL or Fedora.  It contains no files.