85fc411 %pyproject_buildrequires: Avoid leaking stdout from subprocesses

Authored and Committed by churchyard a year ago
    %pyproject_buildrequires: Avoid leaking stdout from subprocesses
    
    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
    
        
file modified
+5 -1
file modified
+29 -5