From Fedora Project Wiki
Important.png
Work In Progress
Things described on this page are Work In Progress. Talk to the Python SIG if you want to discuss it. A counterproposal with bconds exists at User:Churchyard/Packaging:PythonBconds

For packagers who like to share a common spec file between Fedora and EPELs, the following macros are defined in EPEL and Fedora that you can use in conditionals. For each Python runtime, there are 2 versions of the macros: a must version (that says whether the packager must package for that runtime if possible) and a may version (that says that if the packager wants to, they may package for that runtime). Note that even if some macro currently expands to 1 an all Fedoras and EPELs, it might change in the future.

%py3_must %py3_may %py2_must %py2_may
All Fedoras 1 1 undefined 1
EPEL 7 undefined 1 undefined 1
EPEL 6 undefined 1 undefined 1

It's up to the packager whether they conditionalize on the must or may macros, or whether they use those macros at all. See some examples in the appendix.

(The following examples go into appendix:)

Example common spec file with the must/may macros

The following is a very simple spec file for a module building for both python2 and python3 in Fedoras and EPEL. It uses the %py3_must etc. macros so it should build on all possible distributions.

In this example, the packager want's to support as many Python stacks as possible. Substitute all py2_may with py2_must for a more forward looking approach.

%global srcname example

Name:           python-%{srcname}
Version:        1.2.3
Release:        1%{?dist}
Summary:        An example python module

License:        MIT
URL:            https://pypi.python.org/pypi/%{srcname}
Source0:        https://files.pythonhosted.org/packages/source/e/%{srcname}/%{srcname}-%{version}.tar.gz

BuildArch:      noarch

%description
An python module which provides a convenient example.

%if 0%{?py2_may}
%package -n python2-%{srcname}
Summary:        %{summary}
BuildRequires:  python2-devel
BuildRequires:  python2-pytest
%{?python_provide:%python_provide python2-%{srcname}}

%description -n python2-%{srcname}
An python module which provides a convenient example.
%endif


%if 0%{?py3_may}
%package -n python%{python3_pkgversion}-%{srcname}
Summary:        %{summary}
BuildRequires:  python%{python3_pkgversion}-devel
BuildRequires:  python%{python3_pkgversion}-pytest
%{?python_provide:%python_provide python%{python3_pkgversion}-%{srcname}}

%if ! 0%{?py2_may}
Obsoletes:      python2-%{srcname} < %{version}-%{release}
Obsoletes:      python-%{srcname} < %{version}-%{release}
%endif

%description -n python%{python3_pkgversion}-%{srcname}
An python module which provides a convenient example.
%endif

%prep
%autosetup -n %{srcname}-%{version}

%build
%{?py2_may:%py2_build}
%{?py3_may:%py3_build}

%install
%{?py2_may:%py2_install}
%{?py3_may:%py3_install}

%check
%{?py2_may:%{__python2} setup.py test}
%{?py3_may:%{__python3} setup.py test}

%if 0%{?py2_may}
%files -n python2-%{srcname}
%license COPYING
%doc README.rst
%{python2_sitelib}/*
%if ! 0%{?py3_may}
%{_bindir}/sample-exec
%endif
%endif

%if 0%{?py3_may}
%files -n python%{python3_pkgversion}-%{srcname}
%license COPYING
%doc README.rst
%{python3_sitelib}/*
%{_bindir}/sample-exec
%endif

%changelog

You may introduce a following section to top of your spec, if you wish to transition from may to must in Fedora 28:

%if 0%{?fedora} > 27
%{?py2_must:%global py2_use %py2_must}
%else
%{?py2_may:%global py2_use %py2_may}
%endif

And use %py2_use in the conditionals inside the spec file. That way, you don't accidentally drop python2 subpackage from a released Fedora. If you prefer bconds, you can set your with_python2 and with_python3 bconds accroding to a combination of %pyX_must, %pyX_may and Fedora/EL version.

How to test

(not to be part of the guidelines, just this draft)

Add the following section to the very beginning of your spec to test things out:

%if 0%{?fedora}
%global py3_must 1
%global py3_may 1
%global py2_may 1
%endif

%if 0%{?rhel} &&  0%{?rhel} <= 7
%global py3_may 1
%global py2_may 1
%endif

%if 0%{?rhel} > 7
... (use your best judgment here)
%endif

# here starts the actual spec...