Rules
Naming Conventions
These naming guidelines only apply to Python packages whose main purpose is providing a Python library; packages that mainly provide user-level tools that happen to be written in Python do not need to follow these naming guidelines.
- The name of a Python extension/library package must be of the form python-UPSTREAM. If the upstream name UPSTREAM contains “python”, that should be dropped from the name. This is also the name of the directory in svn.
- Packages for Python 3 must be of the form python3-UPSTREAM. This is done by defining a subpackage with this name.
- Please use lower case.
Rationale:
- Using a prefix is serving as a name space, and clearly shows how to find Python modules.
- Having everything in lower case is easier to read, and offers a consistent sorting.
pyc/pyo Policy
Files should be compiled before rpm creation and includes. If you do not include them in your packages, Python will try to create them when the user runs the program. If the system administrator uses them, then the files will be successfully written. Later, when the package is removed, the .pyc and .pyo files will be left behind on the filesystem. To prevent that you need to byte compile the files when building your package and include the files in the %files section.
As often .pyo files are exactly the same as .pyc, the Mageia build system has brp-python-hardlink enabled. This will hardlink these files together (like fdupes does).
Files to Include
When installing Python modules we include several different types of files.
- *.py source files because they are used when generating tracebacks
- *.pyc and *.pyo byte compiled files
- *.egg-info files or directories. If these are generated by the module's build scripts they must be included in the package because they might be needed by other applications and modules at run-time.
Building for Several Versions of Python
As of Mageia 8, only Python 3 is supported. Python 2 packages should no longer be created since there is no Python 2 interpreter with which to run them.
Compile to Byte Code
If Python code is installed into a nonstandard location, it might need to be compiled manually. The %py_byte_compile
macro takes two arguments. The first is the Python interpreter to use for byte compiling. The second is a file or directory to byte compile. If the second argument is a directory, the macro will recursively byte compile any *.py file in the directory.
No %{} for py_byte_compile: RPM macros can only take arguments when they do not have curly braces around them. Therefore, py_byte_compile won't work correctly if you write: %{py_byte_compile} %{__python}
}
Writing the spec-File
Tags
Group should be Development/Python:
Group: Development/Python
For pure Python packages, BuildArch must be noarch:
BuildArch: noarch
BuildRequires
In the typical case, just use:
BuildRequires: python3
If you are building a C extension-modules, use python3-devel, but leave away python3 (which is requires by python3-devel anyway):
BuildRequires: pkgconfig(python3)
As needed add one of:
BuildRequires: python3-setuptools BuildRequires: python3-pip
Requires
- Please do not specify `python3` as a requirement for your package. It will be added automatically in the correct way.
- The %py_requires macro is no longer needed and has been removed.
Sometimes we need to exclude modules from autorequires :
%global __requires_exclude pythonegg\\(3\\)\\(enum34\\)|python3dist\\(enum34\\)
Automatically-generated dependencies take the form python3dist(modname)
which replaces the old style pythonegg(3)(modname)
.
Provides
Packages shouldn’t have explicit provides, as they are automatically added in rpmbuild itself.
But usually we don't want to provide private Python extension libs so please consider using the following:
# we don't want to provide private python extension libs %define _exclude_files_from_autoprov %{python3_sitearch}/.*\\.so
%prep
Typically:
%autosetup -q -n %{fname}-%{version} -p1
%build
Typically:
%py3_build
Do not use the following options for setup.py build:
- '--executable'
- '--plat-name'
%install
Typically:
%py3_install
Do not use the following options for setup.py install:
- '--optimize' or -O': see above
- '--record': this is done automatically
- '--compile' (is default anyway), '--no-compile' (brb-python-bytecompile would compile later anyway)
%check
For example:
%check PYTHONPATH=%{buildroot}%{python3_sitelib} %{__python3} -m unittest discover -s test -p "unittest*.py"
If a module don't have a test suite, a minimal check for a module can be:
%check export PYTHONPATH=%{buildroot}%{python3_sitearch} %{__python3} -c 'import %{module}; print(%{module}.version)'
%files
Typically:
%doc README %{python3_sitelib}/*egg-info %{python3_sitelib}/%{fname}
Macros
The following macros are defined in /etc/rpm/macros.d/:
%python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)") %python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()") %python_version %(%{__python} -c "import sys; print(sys.version[0:3])") %pyver %(python -V 2>&1 | cut -f2 -d" " | cut -f1,2 -d".") %py_prefix %(python -c "import sys; print sys.prefix" 2>/dev/null || echo PYTHON-NOT-FOUND) # backward compatibility %py_libdir %py_purelibdir %py_platlibdir %(python -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib(standard_lib=1,plat_specific=1)' 2>/dev/null || echo PYTHON-LIBDIR-NOT-FOUND) %py_purelibdir %(python -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib(standard_lib=1,plat_specific=0)' 2>/dev/null || echo PYTHON-LIBDIR-NOT-FOUND) %py_incdir %(python -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_inc()' 2>/dev/null || echo PYTHON-INCLUDEDIR-NOT-FOUND) %py_sitedir %py_puresitedir %py_platsitedir %(python -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib(plat_specific=1)' 2>/dev/null || echo PYTHON-LIBDIR-NOT-FOUND) %py_puresitedir %(python -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib()' 2>/dev/null || echo PYTHON-LIBDIR-NOT-FOUND) %py_compile(O) \ find %1 -name '*.pyc' -exec rm -f {} \\; \ python -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1 \ %{-O: \ find %1 -name '*.pyo' -exec rm -f {} \\; \ python -O -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1 \ } %__python3 /usr/bin/python3 %python3_sitelib %(%{__python3} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") %python3_sitearch %(%{__python3} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))") %python3_version %(%{__python3} -c "import sys; print(sys.version[0:3])") %py3_prefix %(%{__python3} -c "import sys; print(sys.prefix)" 2>/dev/null || echo PYTHON-NOT-FOUND) %py3_platsitedir %python3_sitearch %py3_puresitedir %python3_sitelib %py3_incdir %(%{__python3} -c 'from distutils.sysconfig import get_python_inc; print(get_python_inc())' 2>/dev/null || echo PYTHON-INCLUDEDIR-NOT-FOUND) %py3dir %{_builddir}/python3-%{name}-%{version}-%{release} %py3_setup setup.py %py3_shbang_opts -s %py3_build() %{expand:\ CFLAGS="%{optflags}" %{__python3} %{py3_setup} %{?py3_setup_args} build --executable="%{__python3} %{py3_shbang_opts}" %{?1}\ } %py3_install() %{expand:\ CFLAGS="%{optflags}" %{__python3} %{py3_setup} %{?py3_setup_args} install -O1 --skip-build --root %{buildroot} %{?1}\ }
Usage sample of %py3_build :
If you need something like :
python3 setup.py build --use-system-libraries --offline
you can write :
%py3_build -- --use-system-libraries --offline
Tools
There is a tool that can help you to package Python modules from PyPI : https://bitbucket.org/bkabrda/pyp2rpm
It is packaged for Mageia, so you just have to install pyp2rpm. The spec files it generates follow the recommended guidelines.
Samples
Here is a sample of a package build for Python 3 and even including a -doc-subpackage.
%define upstream_name fdb Name: python-fdb Summary: Firebird RDBMS bindings for Python Version: 1.7 Release: %mkrel 3 Source0: https://pypi.io/packages/source/f/%{upstream_name}/%{upstream_name}-%{version}.tar.gz URL: https://www.firebirdsql.org/ Group: Development/Python License: BSD BuildArch: noarch BuildRequires: firebird-devel BuildRequires: python2dist(setuptools) BuildRequires: python3dist(setuptools) %description Set of Firebird RDBMS bindings for Python. %package -n python3-%{upstream_name} Summary: Firebird RDBMS bindings for Python 3 %{?python_provide:%python_provide python3-%{upstream_name}} %description -n python3-%{upstream_name} Set of Firebird RDBMS bindings for Python. %package doc Summary: Documentation for %{name} Group: Documentation License: BSD %description doc Documentation files for %{name}. %prep %autosetup -n %{upstream_name}-%{version} rm -rf %{upstream_name}.egg-info %build %py3_build %install %py3_install %files -n python3-%{upstream_name} %doc README %license LICENSE.TXT %{python3_sitelib}/* %files doc %doc docs/* %license LICENSE.TXT
References
Policy in other distributions
- Fedora Python packaging policy. Mageia policy is almost identical to Fedora's; the exceptions are that we still set
Group:
andRelease:
takes the form%mkrel 2
. - Debian Python packaging policy
- OpenSuse Python packaging policy