When the build backend prints to stdout via non-Python means,
for example when a setup.py script calls a verbose program via os.system(),
the output leaked to stdout of %pyproject_buildrequires was treated as generated BuildRequires.
Fore example, if the setup.py script has:
rv = os.system('/usr/bin/patch -N -p3 -d build/lib < lib/py-lmdb/env-copy-txn.patch')
(From https://github.com/jnwatson/py-lmdb/blob/py-lmdb_1.0.0/setup.py#L117)
The stdout of /usr/bin/patch leaked to stdout of %pyproject_buildrequires:
[lmdb-1.0.0]$ /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --python3_pkgversion 3 2>/dev/null
python3dist(setuptools) >= 40.8
python3dist(wheel)
patching file lmdb.h
patching file mdb.c
python3dist(wheel)
patching file lmdb.h
patching file mdb.c
This resulted in DNF errors like this:
No matching package to install: 'lmdb.h'
No matching package to install: 'mdb.c'
No matching package to install: 'patching'
Moreover, it resulted in bogus BuildRequires that may have existed (e.g. "file").
By replacing the usage of contextlib.redirect_stdout
(which only redirects Python's sys.stdout)
with a custom context manager that captures stdout on file descriptor level
(in addition to Python's sys.stdout),
we avoid this leak.
File descriptor magic heavily inspired by the capfd pytest fixture.
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=2166888
pyproject-srpm-macros is intended to be installed in the default buildroot.
That way, no explicit BuildRequires for pyproject-rpm-macros are required,
as long as %pyproject_buildrequires is used in %generate_buildrequires.
When only pyproject-srpm-macros is installed, the minimal implementation of
%pyproject_buildrequires generates a dependency on pyproject-rpm-macros.
When pyproject-rpm-macros is installed, it overrides the implementation
of %pyproject_buildrequires with the full one.
Note that in Fedora, pyproject-rpm-macros is required by python3-devel,
but not in RHEL.
This allows us to keep pyproject-rpm-macros in the RHEL CRB repository.
That way, if a package (such as python-tox) uses it,
the patches in dist-git are available.
In the future, it also allows us to add patches without URLs to our tested spec files.
The new %py3_test_envvars macro was added
to remove duplication of environment variables used in %check.
We reuse it in %tox to gain support e.g. for PYTEST_XDIST_AUTO_NUM_WORKERS.
However, we keep support for platforms where the macro is not yet available,
not to be forced to backport %py3_test_envvars everywhere right away.
Technically, this should change little, but it sets CFLAGS and LDFLAGS now,
hence a new Y version.
Before:
usage: %pyproject_buildrequires [-w] [-R] [-e TOXENVS] [-t] [-x EXTRAS] [-N] [REQUIREMENTS.TXT ...]
After:
usage: %pyproject_buildrequires [-x EXTRAS] [-t] [-e TOXENVS] [-w] [-R] [-N] [REQUIREMENTS.TXT ...]
The order was determined as:
0. suppressed options
1. extras, the easiest way to specify test deps (x)
2. tox related options (te)
3. build wheel, as it is provisional (w)
4. "disablers" (RN)
5. varargs are always listed last
Previous order was pretty much random.
When certain modules are deliberately not included into the built RPM,
they shouldn't be listed in the list of qualified module names which are
used by %pyproject_check_import to test importability of the
distribution.
Resolves: https://bugzilla.redhat.com/2127958
Files still need to be marked as License-File to be considered %license,
but if their path in METADATA is specified relative to dist-info/licenses,
they are correctly recognised.
This makes License-Files specified by hatchling 1.9.0+ marked as %license.
Users invoking %pyproject_save_files with glob: '*' don't care about the
files in the Python package, hence it shouldn't error when no modules
are detected.
There may be legitimate reasons to create a package without Python
modules in it, hence we shouldn't be blocking this possibility.
When extension modules are built in %pyproject_buildrequires,
we need to create the package note file.
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=2097535
This is tested via python-ldap -- %pyproject_buildrequires -w fails without the fix.
Neither python-markupsafe nor python-mistune can be used as a test
because they only warn when the extension module cannot be built
because they fallback to pure Python.
Apparently, when you repeatedly run `rpmbuild -ba`, files in %_builddir are not cleaned.
This way, we at least make sure the files are unique between different NVRAs,
so 2 unrelated builds don't share the files between each other.
Keeping files contained in the build subdirectory is the more common way of doing this,
but we cannot technically do that, because we don't know what's it gonna be (before %prep).
Should be backwards compatible, as we only modify underscore-prefixed macros and %{pyproject_files},
where the exact value should not matter to the packagers.