Previous implementation allowed for only one argument to be passed to
the %pycached macro, which made it impossible to combine it with other macros.
Current implementation allows to pass other macros as arguments to
%pycached.
Example:
%pycached %exclude /path/to/foo.py
For macro expansion limitations, the opposite order is not possible.
That is to be documented in the guidelines:
https://pagure.io/packaging-committee/pull-request/986
Added some tests.
Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1838992
Co-authored-by: Marcel Plch <mplch@redhat.com>
To avoid mock using a local copy of python-srpm-macros from the buildroot cache
and having Python version defined to 3.8 until the cache expires.
Also, other surprises happened in the past, so we stop playing it cool and
actually follow the guidelines here.
%pyhon_provide in python-rpm-macros uses new Lua functions from python-srpm-macros
People have python-srpm-macros pre-installed, and it is not autoupdated,
hence they can have older versions installed and it blows up.
- 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/