From Fedora Project Wiki

< User:Orion

Revision as of 18:43, 27 February 2015 by Orion (talk | contribs) (→‎Explanation)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

EPEL 7 in Python 3 Plan Draft

Why Python 3 in EPEL 7, Why not SCLs

Due to Fedora plans for migration to Python 3 [1], it is becoming necessary to have Python 3 accessible in some form in EPEL 7. This will allow upstream projects to move to Python 3 (dropping Python 2 support) and still be usable through EPEL repositories. Some key stakeholders in this regard are Fedora Infra and DNF.

Another important reason is further promotion of Python 3 and raising awareness for enterprise-level Python users.

Because of key stakeholders like Fedora Infra and DNF, SCLs as a solution to this problem were ruled out. SCLs are currently not allowed in EPEL (and it seems they won't be allowed in near future) and since these projects need/strongly prefer to be in EPEL itself, SCLs are not a viable alternative for them.

Some Facts

  • Python 3 is actively developed by upstream and new minor versions are released approximately every year. Latest Python 3 minor is 3.4.
  • Python minor versions are not ABI compatible, rebuilds are needed (both because of libpython soname change and because of bytecode magic numbers).
  • Python has a good support for parallel installable stacks, even for minor versions of one major version (e.g. 3.3 and 3.4 can easily be installable alongside).
  • EPEL policies try to discourage updates that break ABI and require rebuilds of other packages - due to the above fact, I consider Python minor version update a "major version update" as specified in EPEL update guidelines [2]. And as the guidelines say, this should be avoided if at all possible.


  • Python 3 is packaged as python3X parallel-installable package (X is minor version, e.g. "4" ATM) that can coexist with other parallel installable python3Y stacks.
  • One of these stacks is always considered the "default" in the sense that it owns /usr/bin/python3.
  • All binary RPMs of extension packages must be named python3X-foo. They must follow Fedora's python3 packaging guidelines with the exception that name contains both major and minor Python version (in Fedora it's only major). See below for packaging instructions.
  • Most of the time, there is only one python3X stack in EPEL. During transitional periods, after 3X+1 is released, there are two.
  • In a situation when python3X is in EPEL and 3.X+1 is released upstream, the following happens:
    • python3X+1 package is created for EPEL ASAP and all extension packages are built also for this new python3X+1 stack.
    • When all packages are rebuilt for python3X+1, the old python3X stack is retired after certain period. This period gives everyone enough time to rebuild their packages while being as short as possible. There is intentionally no hard limit here, we will approach this case by case.
    • "/usr/bin/python3" belongs to the "stable" python3X stack. Switching /usr/bin/python3 from python3X to python3X+1 happens shortly before the end of transitional period (== before obsoleting python3X) and it is announced on epel-devel.

I'm not sure about this below - I think it could ease in user's transition from python3X to 3X+1 when the packaging providing /usr/bin/python3 changes.

    • Usage of "/usr/bin/python3" is discouraged in favour of using /usr/bin/python3.X explicitly.

Packaging Parallel python3X stacks

  • Automatic dependency generators and bytecompilation hooks work fine.
  • RPM naming:
    • As mentioned above, binary RPMs are named python3X for Python itself and python3X-foo for extension packages.
  • SRPM naming, dist-git:
    • We're using Fedora-like dist-git repos:
      • If a python3-foo Fedora repo exists, it must be used.
      • Otherwise if python-foo Fedora repo exists, it must be used.
      • Otherwise the package doesn't exist in Fedora and packager should decide before review which of the above he'll choose to have created, according to Fedora Python Packaging Guidelines.
    • SRPM names are same as dist-git repo names. This means that we can have python-foo dist-git repo and python-foo SRPM which produces just python34-foo RPM, while not producing python-foo RPM.
subpackages for Python 2 already in RHEL
Some packages imported from Fedora, for example setuptools, already have their Python 2 versions built in RHEL and these must not be replaced/updated by EPEL packages. For these packages a python3-foo package must be introduced for EPEL.

Specfiles, Macros, Packaging Process

An example specfile follows:

# note: macros %%python3_pkgversion and %%python3_next_pkgversion are defined by a macrofile from package
#  python3-pkgversion-macros that is present in minimal buildroot; %%python3_pkgversion is also available
#  on Fedora, so it's possible to have a common specfile for EPEL and Fedora
%global with_python3 1
# this is only turned on during transitional periods
%{?python3_next_pkgversion: %global with_python3_next 1}

Name:           python-X
Version:        1
Release:        1%{?dist}
Summary:        X
Source:         X

License:        MIT
URL:            http://X
%if 0%{?with_python3}
# BR: python%{python3_pkgversion}-devel
# and other BR

%if 0%{?with_python3_next}
# BR: python%{python3_next_pkgversion}-devel
# and other BR


%if 0%{?with_python3}
%package -n python%{python3_pkgversion}-X
Summary: python%{python3_pkgversion} build of X

%description -n python%{python3_pkgversion}-X
python%{python3_pkgversion} build of X.

%if 0%{?with_python3_next}
%package -n python%{python3_next_pkgversion}-X
Summary: python%{python3_next_pkgversion} build of X

%description -n python%{python3_next_pkgversion}-X
python%{python3_next_pkgversion} build of X.

%setup -q -n X-%{version}

%if 0%{?with_python3}
# do what you do for Fedora's Python 3 stack

%if 0%{?with_python3_next}
# do the same as above, just with python3_next macro set

# do it like in Fedora, add with_python3_next

# do it like in Fedora, add with_python3_next

%if 0%{?with_python3}
%files -n python%{python3_pkgversion}-X

%if 0%{?with_python3_next}
%files -n python%{python3_next_pkgversion}-X


For start, packagers are able to merge specfile from Fedora and use it - all macros like %__python3 or %python3_sitelib are provided by the current python3X-devel. It's even be possible to use the same specfile for Fedora and EPEL with minimal effort.

  • do initial Fedora import
  • change Fedora's python3-X subpackage name to python%{python3_pkgversion}-X, change BuildRequires and Requires in the same way for this subpackage
  • add %{?python3_next_pkgversion: %global with_python3_next 1} line
  • add definition and %prep, %build and %install (and %check) steps of python%{python3_next_pkgversion}-X subpackage. which looks exactly the same as python%{python3_pkgversion}-X subpackage, it just uses different macros; build of this subpackage has to be conditionalized by the %with_python3_next macro
  • TODO: provide the macro names and definitions here

Lifecycle of python3X stacks, rebuilding:

  • when a new python3X+1 is built in EPEL - let's say that there is python34 and python35 has just been introduced:
    • A new python3-pkgversion-macros is build defining the %python3_next* macros.
    • (scripted) mass rebuild is run to build as much of the new stack possible automatically.
    • At some point /usr/bin/python3 is switched from python34 to python35.
    • at a certain point at time an announcement is made that python34 is to be retired and python35 is to be *the* one. At this point:
      • python3-pkgversion-macros is rebuilt removing the %python3_next* macros and bumping %python3_pkgversion to 35.
      • python35 is rebuilt defining the normal %python3_* macros.
      • All python34 packages are retired.
    • At this point all packages build just python35-X subpackages
User End

What does this look like on the user end?

[1] [2]