Package Python projects with pyproject RPM macros

Package Python projects that use a pyproject.toml or a setup.py file into RPM packages by using pyproject RPM macros from the CodeReady Linux Builder (CRB) repository.

pyproject RPM macros for Python packaging

Package Python projects into RPM packages by using pyproject RPM macros. These macros work with projects that define metadata in setup.py, pyproject.toml, or both, and invoke a standards-based build backend through a standardized protocol.

Many upstream Python projects no longer rely on a setup.py script. Instead, they store project metadata in pyproject.toml and use a build backend, such as setuptools, flit-core, hatchling, or poetry-core. The pyproject RPM macros invoke any compliant build backend through a standardized protocol instead of calling setup.py directly.

The pyproject RPM macros reuse upstream metadata whenever possible. For example, they can generate BuildRequires from the build-system requirements in pyproject.toml instead of listing the same dependencies manually in the spec file.

The pyproject-rpm-macros package is available in the CodeReady Linux Builder (CRB) repository. The %pyproject_buildrequires macro adds a generated BuildRequires on that package during package builds. CRB content is unsupported by Red Hat. The macros are updated as needed to follow emerging Python packaging standards.

Use pyproject RPM macros to package Python projects, whether the upstream project defines metadata in setup.py, pyproject.toml, or both.

Prepare to use pyproject RPM macros

To package Python projects with pyproject RPM macros, enable the CodeReady Linux Builder (CRB) repository on the build host and configure %pyproject_buildrequires in your RPM spec file.

Before you begin

  • You have root permissions on the build host.
  • The system is registered with Red Hat Subscription Manager.

About this task

Important

Red Hat does not support content in the CodeReady Linux Builder repository.

Procedure

  1. Enable the CodeReady Linux Builder repository on the build host:
    # subscription-manager repos --enable codeready-builder-for-rhel-10-x86_64-rpms
  2. In the RPM spec file, add BuildRequires: python3-devel and use the %pyproject_buildrequires macro in the %generate_buildrequires section:
    BuildRequires: python3-devel
    
    %generate_buildrequires
    %pyproject_buildrequires

Common pyproject RPM macros for Python 3 RPMs

In a Python RPM spec file, use pyproject RPM macros to build projects that define metadata in setup.py, pyproject.toml, or both.

You can redefine which Python 3 version the macros use by defining the python3_pkgversion macro at the top of your spec file, for example %global python3_pkgversion 3.14. Omit this macro to build for the default Python 3 version.

Place %pyproject_buildrequires in the %generate_buildrequires section of the spec file. RPM runs the macro in that section to generate build requirements from upstream metadata before the build starts.

Table 1. Common pyproject RPM macros for Python 3 RPMs
Macro Description

%pyproject_buildrequires

Expands build requirements from upstream metadata. Use options such as -g test to include dependencies from a named dependency group.

%pyproject_wheel

Builds a wheel package by using the upstream-specified build backend.

%pyproject_install

Installs the built wheel package into the build root.

%pyproject_save_files

Saves the list of installed files for use in the %files section. Use -l to assert that a license file is found.

%pyproject_check_import

Verifies that the installed package can be imported during the %check section.

%pyproject_files

Expands to the file list saved by %pyproject_save_files. Use it with the -f option in the %files section.

The table lists commonly used macros. For all macros and their options, see the /usr/share/doc/pyproject-rpm-macros/README.md file provided by the pyproject-rpm-macros package.

A spec file description for a Python package with pyproject RPM macros

Use an annotated RPM spec file example to package a Python project that defines metadata in setup.py, pyproject.toml, or both. The example shows pyproject RPM macros for build requirements, wheel builds, installation, and automated file lists.

An example spec file for a Python library built with pyproject RPM macros

Name:           python-pello
Version:        1.0.2
Release:        1%{?dist}
Summary:        Example Python library

License:        MIT
URL:            https://example.com/Pello
Source:         %{url}/archive/v%{version}/Pello-%{version}.tar.gz

BuildArch:      noarch

%description %_description
Pello is an example package with an executable that prints Hello World! on the command line.

%package -n python3-pello
Summary:        %{summary}

%description -n python3-pello
Pello is an example package with an executable that prints Hello World! on the command line.

%prep
%autosetup -p1 -n Pello-%{version}

%generate_buildrequires
%pyproject_buildrequires

%build
%pyproject_wheel

%install
%pyproject_install

%pyproject_save_files -l pello

%check
%pyproject_check_import
%pytest

%files -n python3-pello -f %{pyproject_files}
  • The %pyproject_buildrequires macro in the %generate_buildrequires section creates build requirements from upstream metadata.
  • The %pyproject_wheel macro builds a wheel package by using the upstream-specified build backend.
  • The %pyproject_install macro installs the wheel into the build root.
  • The %pyproject_save_files -l pello macro records installed files. The -l option verifies that a license file is present. The pello argument lists the importable module named pello.
  • The %check section runs %pyproject_check_import to verify importability and %pytest to run tests.
  • The %files section uses -f %{pyproject_files} to include the file list generated by %pyproject_save_files.

For commonly used macros, see Common pyproject RPM macros for Python 3 RPMs. For all macros and their options, see the /usr/share/doc/pyproject-rpm-macros/README.md file provided by the pyproject-rpm-macros package.