- Hardcode the default Python 3 version in the SRPM macros
- Provide python38-foo for python3-foo and the other way around (future RHEL compatibility)
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1812087
$ rpm --eval '%python_provide python38-setuptools'
Provides: python-setuptools = %{version}-%{release}
Provides: python3-setuptools = %{version}-%{release}
Obsoletes: python-setuptools < %{version}-%{release}
$ rpm --eval '%python_provide python3-setuptools'
Provides: python-setuptools = %{version}-%{release}
Provides: python38-setuptools = %{version}-%{release}
Obsoletes: python-setuptools < %{version}-%{release}
$ rpm --eval '%python_provide python39-setuptools'
$ rpm --define 'python3_pkgversion 39' --eval '%python_provide python%{python3_pkgversion}-setuptools'
To make the implementation of %python_provide easier,
any names starting with "python" or "pypy" are recognized as valid arguments.
Previously, this was an ERROR:
$ rpm --eval '%python_provide pythonista'
%python_provide: ERROR: pythonista not recognized.
Now it is a no-op. The behavior was never documented and the change is
backwards compatible for working spec files.
The Python compileall2 module in /usr/lib/rpm/redhat/
can be executed by various different Python interpreters.
We don't want to write several different `*.pyc` files
to this location - in most cases, that's not possible,
but somebody might run this as root.
Usage:
%files
...
%pycached %{python3_sitelib}/foo.py
This will list:
/usr/lib/python3.8/site-packages/foo.py
/usr/lib/python3.8/site-packages/__pycache__/foo.cpython-38{,.opt-?}.pyc
Assuming the Python 3 version is 3.8.
The bytecode files are globbed, their presence is not checked.
This will fail:
%pycached %{python3_sitelib}/foo
error: %pycached can only be used with paths explicitly ending with .py
And so will any of this:
%pycached %{python3_sitelib}/*
%pycached %{python3_sitelib}/foo.*
%pycached %{python3_sitelib}/foo.p?
%pycached %{python3_sitelib}/foo.?y
%pycached %{python3_sitelib}/foo.??
But this will work:
%pycached %{python3_sitelib}/foo*.py
And it will generate the following globs:
/usr/lib/python3.8/site-packages/foo*.py
/usr/lib/python3.8/site-packages/__pycache__/foo*.cpython-38{,.opt-?}.pyc
When used with paths that include Python 3 version, it globs with the version:
%pycached /opt/python3.10/foo.py
Generates:
/opt/python3.10/foo.py
/opt/python3.10/__pycache__/foo.cpython-310{,.opt-?}.pyc
While paths without version have less strict globs:
%pycached /custom/foo.py
/custom/foo.py
/custom/__pycache__/foo.cpython-3*{,.opt-?}.pyc
This will generate a warning in RPM build:
warning: File listed twice: /custom/__pycache__/foo.cpython-38.opt-1.pyc
However it ensures the optimized bytecode is there.
Resolves: rhbz#1595265
The problem this change is intended to solve is with how `real_libdir`
is calculated. Let's assume we want to recursively byte-compile all
`*.py` files in
`/builddir/build/BUILDROOT/python-scales-1.0.9-250.fc32.x86_64/usr/lib/python3.8`.
Then, `real_libdir` is this path without `$RPM_BUILD_ROOT` with
the filename at the end which displays in the error message like this:
```
Bytecompiling .py files below /builddir/build/BUILDROOT/python-scales-1.0.9-250.fc32.x86_64/usr/lib/python3.8 using /usr/bin/python3.8
*** Error compiling '/builddir/build/BUILDROOT/python-scales-1.0.9-250.fc32.x86_64/usr/lib/python3.8/site-packages/greplin/bar.py'...
File "/usr/lib/python3.8/bar.py", line 1
import sin from math
^
SyntaxError: invalid syntax
```
`/usr/lib/python3.8/bar.py` is obviously wrong.
One of the new features of the `compileall2` module (which will
be available in stdlib in Python 3.9) is that the path byte-compiled to
`*.pyc` files is calculated for each file. This means that by using
`-s` and `-p` we can strip `$RPM_BUILD_ROOT` and prepend `/` for each
file individually which will fix the problem.
```
Bytecompiling .py files below /builddir/build/BUILDROOT/python-scales-1.0.9-250.fc32.x86_64/usr/lib/python3.8 using /usr/bin/python3.8
*** Error compiling '/builddir/build/BUILDROOT/python-scales-1.0.9-250.fc32.x86_64/usr/lib/python3.8/site-packages/greplin/bar.py'...
File "/usr/lib/python3.8/site-packages/greplin/bar.py", line 1
import sin from math
^
SyntaxError: invalid syntax
```
This change has an effect only for Python >= 3.4.
Based on recent changes in 04769fa014,
packagers might want to use:
%{?python_provide:%python_provide python2-foo%{?_isa}}
...for backwards compatibility. However the macro adds obsoletes and
since RPM 4.15, obsoletes with %{?_isa} are not possible:
Only package names are allowed in Obsoletes: Obsoletes: python-foo(x86-64) < ...
To allow such usage, %python_provide now only obsoletes if the argument
does not end with ")".
In rpm 4.15 those are no longer defined.
The meaning of "python" is derived from %__python - and that errors by default
unless user defined.
Example usage:
%global __python /usr/bin/pypy3
...
%files
%{python_sitelib}/foo/
This is needed so people can do things like:
%if %{with python3}
%global __python %__python3
%else
%global __python %__python2
%else
And than just use %__python, %py_build, %py_install,
%python_sitelib, ...
This is mostly used when building Sphinx docs on arched build.
Previously:
PLATFORM=$(python3 -c "import sysconfig; print(sysconfig.get_platform())")
export PYTHONPATH=../build/lib.${PLATFORM}-%{python3_version}
make man
Or:
PYTHONPATH=`realpath ../build/lib.linux*` make
Or:
PYTHONPATH=$(echo $PWD/build/lib.linux-*) make html
Now:
PYTHONPATH=../build/lib.%{python3_platform}-%{python3_version}
Adds the %pypi_source macro, as well as %__pypi_url and
%__pypi_default_extension. This should make references to sources in
PyPI much simpler for nearly all Python packages.