Remove dependency on /usr/bin/python3
Hello, As part of a Python team maintenance task we are trying to remove the dependency on /usr/bin/python3 from as many packages as possible to reduce the problems of changing the system python in the future [1]. Right now /usr/bin/python3 is a link provided by the current system python package that today is python311, in Factory. Any package that provides a python script with the shebang #!/usr/bin/python3 will have the requirement on /usr/bin/python3. There's a macro in the python-rpm-macros to fix the shebang on python scripts automatically, that can be used in the install phase, just before the fdupes call, and point to the real binary and not the link: %python3_fix_shebang This macro expands to: for f in /home/abuild/rpmbuild/BUILDROOT/%{NAME}-%{VERSION}- %{RELEASE}.x86_64/usr/bin/*; do [ -f $f ] && sed -i "1s@#!.*python.*@#!$(realpath /usr/bin/python3)@" $f done And indeed will replace the shebang to point to #!/usr/bin/python3.11. This will make the script to work correctly, even if the system python changes in the distribution, avoiding the problem of running with a different python and not finding the deps that are in /usr/lib/python3.11/site- packages. In some cases it could be okay to have the shebang #!/usr/bin/python3, if there are no external dependencies and it's something that will work with different python versions, but when possible, and as a general rule, it'll be better to fix the shebangs. If you maintain a package that provides some python script, please, consider to add this macro call. [1] https://bugzilla.opensuse.org/show_bug.cgi?id=1212476 -- Daniel García Moreno Python Packager
On Tue Oct 10, 2023 at 8:22 AM CEST, Daniel Garcia via openSUSE Factory wrote:
If you maintain a package that provides some python script, please, consider to add this macro call.
Hi, Daniel, I am sorry for not mentioning it before, but it was still niggling in my head and I haven’t caught it on time: couldn’t we somehow call this macro inside of our regular ones like %pyproject_wheel or %pyproject_install (whereever it is more apporpriate)? It seems unfair to lay another burden on our poor package mainatainers. Best, Matěj -- https://matej.ceplovi.cz/blog/, Jabber: mcepl@ceplovi.cz GPG Finger: 3C76 A027 CA45 AD70 98B5 BC1D 7920 5802 880B C9D8 A man who won’t die for something is not fit to live.
Am 10.10.23 um 10:25 schrieb Matěj Cepl:
On Tue Oct 10, 2023 at 8:22 AM CEST, Daniel Garcia via openSUSE Factory wrote:
If you maintain a package that provides some python script, please, consider to add this macro call. Hi, Daniel,
I am sorry for not mentioning it before, but it was still niggling in my head and I haven’t caught it on time: couldn’t we somehow call this macro inside of our regular ones like %pyproject_wheel or %pyproject_install (whereever it is more apporpriate)? It seems unfair to lay another burden on our poor package mainatainers.
Please see my comments in the PR, when I implemented this half a year ago. It's already part of %*pyproject_install. https://github.com/openSUSE/python-rpm-macros/pull/155
It is called implicitly in|%<flavor>_pyproject_install|,*but not in the deprecated|%<flavor>_install|.*The latter would require more effort to implement, because adding lines to the macro would prevent the common pattern to append arguments directly after the currently parameterless macro.
In a|%define pythons python3|build environment,|%python3_fix_shebang|creates the shebang with the resolved symlink where|%{_bindir}/python3|points to. This is the only use case where the macro makes sense. When installing entry-points, Pip and Setuptools normally create the interpreter lines with the same interpreter as they are called by. Thus|python3 setup.py install|(from|%python3_install|) or|python3 -mpip install ...|would create a shebang pointing to|python3|, but the macro fixes it to the current primary interpreter (|/usr/bin/python3.10|).
It's also noteworthy that this macrois only really useful, if you use the singlespec macros with %python_subpackagesfor rewriting the Requires and %python_module for the BuildRequires tags. A package python3-foo (or just foo) directly defining a `Requires: python3-bar` package but using the %python3_fix_shebang macro will make things worse: If foo fails to rebuild at the time of the primary interpreter switch from python311 to python312, will require the old interpreter python3.11 through their hardcoded she-bang. But a sucessfully rebuilding python3-bar will move bar to the new python312 sitelib, out of reach from foo. So nothing gained by the new macro except that the interpreter and the foo module will fit together. Worse: If foo has just a script foobar.py using python3-bar bat not its own foo in sitelib, it will stop working through the move of bar. With generic python3 shebang the old installed script foobar.py would still work with the new python3-bar. Thus, it is rarely useful to explicitly use the macro. Those packages benefiting from it already do use it implicitly, or can be made to use it by switching from the deprecated %python_{build,install} to %pyproject_{wheel,install}. And for the others it makes things worse. - Ben
Moin, On Tue, 10 Oct 2023, 08:22:54 +0200, Daniel Garcia via openSUSE Factory wrote:
Hello,
As part of a Python team maintenance task we are trying to remove the dependency on /usr/bin/python3 from as many packages as possible to reduce the problems of changing the system python in the future [1].
Right now /usr/bin/python3 is a link provided by the current system python package that today is python311, in Factory. Any package that provides a python script with the shebang #!/usr/bin/python3 will have the requirement on /usr/bin/python3.
There's a macro in the python-rpm-macros to fix the shebang on python scripts automatically, that can be used in the install phase, just before the fdupes call, and point to the real binary and not the link:
%python3_fix_shebang
This macro expands to:
for f in /home/abuild/rpmbuild/BUILDROOT/%{NAME}-%{VERSION}- %{RELEASE}.x86_64/usr/bin/*; do [ -f $f ] && sed -i "1s@#!.*python.*@#!$(realpath /usr/bin/python3)@" $f done
And indeed will replace the shebang to point to #!/usr/bin/python3.11. This will make the script to work correctly, even if the system python changes in the distribution, avoiding the problem of running with a different python and not finding the deps that are in /usr/lib/python3.11/site- packages.
In some cases it could be okay to have the shebang #!/usr/bin/python3, if there are no external dependencies and it's something that will work with different python versions, but when possible, and as a general rule, it'll be better to fix the shebangs.
If you maintain a package that provides some python script, please, consider to add this macro call.
What I don't understand is, will this fix be run only at package installation, or will it also be triggered when a new system python package is installed and the previous one will be removed? If only at package installation, I'm afraid all of a sudden all python scripts will stop to work.
[1] https://bugzilla.opensuse.org/show_bug.cgi?id=1212476
-- Daniel García Moreno Python Packager
Cheers. l8er manfred
On mar, 2023-10-10 at 10:32 +0200, Manfred Hollstein wrote:
Moin,
On Tue, 10 Oct 2023, 08:22:54 +0200, Daniel Garcia via openSUSE Factory wrote:
Hello,
As part of a Python team maintenance task we are trying to remove the dependency on /usr/bin/python3 from as many packages as possible to reduce the problems of changing the system python in the future [1].
Right now /usr/bin/python3 is a link provided by the current system python package that today is python311, in Factory. Any package that provides a python script with the shebang #!/usr/bin/python3 will have the requirement on /usr/bin/python3.
There's a macro in the python-rpm-macros to fix the shebang on python scripts automatically, that can be used in the install phase, just before the fdupes call, and point to the real binary and not the link:
%python3_fix_shebang
This macro expands to:
for f in /home/abuild/rpmbuild/BUILDROOT/%{NAME}-%{VERSION}- %{RELEASE}.x86_64/usr/bin/*; do [ -f $f ] && sed -i "1s@#!.*python.*@#!$(realpath /usr/bin/python3)@" $f done
And indeed will replace the shebang to point to #!/usr/bin/python3.11. This will make the script to work correctly, even if the system python changes in the distribution, avoiding the problem of running with a different python and not finding the deps that are in /usr/lib/python3.11/site- packages.
In some cases it could be okay to have the shebang #!/usr/bin/python3, if there are no external dependencies and it's something that will work with different python versions, but when possible, and as a general rule, it'll be better to fix the shebangs.
If you maintain a package that provides some python script, please, consider to add this macro call.
What I don't understand is, will this fix be run only at package installation, or will it also be triggered when a new system python package is installed and the previous one will be removed?
If only at package installation, I'm afraid all of a sudden all python scripts will stop to work.
Maybe I didn't explain it correctly, this macro fixes the shebang at package build time, so the rpm generated will have a "Requires: /usr/bin/python3.11" instead of "Requires: /usr/bin/python3". The scripts in /usr/bin will have the shebang "#!/usr/bin/python3.11", so this package will continue working even if a new python is installed, because the previous python should still be in the system or the package will be removed / updated by zypper. The macro should be added to the "%install" section in the .spec file, but nothing new is run at installation time. -- Daniel García Moreno Python Packager
On Tue Oct 10, 2023 at 10:32 AM CEST, Manfred Hollstein wrote:
What I don't understand is, will this fix be run only at package installation, or will it also be triggered when a new system python package is installed and the previous one will be removed?
If only at package installation, I'm afraid all of a sudden all python scripts will stop to work.
We have OBS and continuous rebuilds, when new Python interpreter happens everything depending on it will get rebuilt and only when it gets through staging process it can get to Factory. Yes, we are drastically extending number of packages which will need to be tested when new interpreter happens, but it is more getting closer to reality than creating additional work for us. Matěj -- https://matej.ceplovi.cz/blog/, Jabber: mcepl@ceplovi.cz GPG Finger: 3C76 A027 CA45 AD70 98B5 BC1D 7920 5802 880B C9D8 Therefore, faithful Christian, seek truth, hear truth, learn truth, love truth, speak truth, hold truth, defend truth until death: because truth will free you from sin, from devil, from the death of soul and finally from the death eternal, which is a separation from God’s mercy. -- Master John Hus, Explanation of Credo, 1412
Hi Daniel, Am Dienstag, 10. Oktober 2023, 08:22:54 CEST schrieb Daniel Garcia via openSUSE Factory:
Right now /usr/bin/python3 is a link provided by the current system python package that today is python311, in Factory. Any package that provides a python script with the shebang #!/usr/bin/python3 will have the requirement on /usr/bin/python3.
Does it catch the /usr/bin/env python[3] as well? Cheers Axel
On mar, 2023-10-10 at 13:13 +0200, Axel Braun wrote:
Hi Daniel,
Am Dienstag, 10. Oktober 2023, 08:22:54 CEST schrieb Daniel Garcia via openSUSE Factory:
Right now /usr/bin/python3 is a link provided by the current system python package that today is python311, in Factory. Any package that provides a python script with the shebang #!/usr/bin/python3 will have the requirement on /usr/bin/python3.
Does it catch the /usr/bin/env python[3] as well?
Yes, it should work with that shebang too, it will replace any shebang with python in it, this is the regular expression used [1]: sed -i "1s@#!.*python.*@#!$(realpath %__#FLAVOR#)@" $f [1] https://github.com/openSUSE/python-rpm-macros/blob/master/flavor.in#L106 -- Daniel García Moreno Python Packager
Am 10.10.23 um 13:13 schrieb Axel Braun:
Hi Daniel,
Am Dienstag, 10. Oktober 2023, 08:22:54 CEST schrieb Daniel Garcia via openSUSE Factory:
Right now /usr/bin/python3 is a link provided by the current system python package that today is python311, in Factory. Any package that provides a python script with the shebang #!/usr/bin/python3 will have the requirement on /usr/bin/python3. Does it catch the /usr/bin/env python[3] as well?
It only catches stuff in %_bindir. For scripts in other places of an installation, which rpmlint frequently complains about, it is best that the packager decides whether it is better to fix or remove the interpreter line. Most of the time such scripts are not really meant to be executable in a system-wide installation anyway.
Cheers Axel
- Ben
Thank you for raising this Axel. Using /usr/bin/env python3 works for me since the responsibility to bump is not on user anymore. Which brings me to my concern with the annoucement is that we move responsibility from a "system" to maintainers or some mass bump in devel:python (again maintainer(s)). Bumping shebang sounds like too much work with every system-python change (I'm aware of the macro which covers it, if maintainer didn't do the job). I suppose customer would not have to deal with it as changes on SLES / ALP would be not so often. Just my thoughts Lubos On Tue, 2023-10-10 at 13:13 +0200, Axel Braun wrote:
Hi Daniel,
Am Dienstag, 10. Oktober 2023, 08:22:54 CEST schrieb Daniel Garcia via openSUSE Factory:
Right now /usr/bin/python3 is a link provided by the current system python package that today is python311, in Factory. Any package that provides a python script with the shebang #!/usr/bin/python3 will have the requirement on /usr/bin/python3.
Does it catch the /usr/bin/env python[3] as well?
Cheers Axel
Hi Lubos, Am Mi., 22. Nov. 2023 um 10:01 Uhr schrieb Lubos Kocman via openSUSE Factory <factory@lists.opensuse.org>:
Using /usr/bin/env python3 works for me since the responsibility to bump is not on user anymore.
It doesn't work because the rpm requirements will be on /usr/bin/env not on /usr/bin/python3, aka incorrect. We should rewrite such shebangs instead.
Bumping shebang sounds like too much work with every system-python change (I'm aware of the macro which covers it, if maintainer didn't do the job).
it wouldn't have to be done on every system python change. it can be done on every build automatically (so no human intervention is needed) or it can be done on every manual bump when the package maintainer has validated the new python version. Also, it can simply be left at /usr/bin/python3 specifying "don't care about which specific version it is". I think this is a fairly flexible approach that should cover most if not all usecases. Greetings, Dirk
On Wed Nov 22, 2023 at 10:01 AM CET, Lubos Kocman via openSUSE Factory wrote:
Using /usr/bin/env python3 works for me since the responsibility to bump is not on user anymore.
Any packaged script in `/usr/bin` with the shebang `#!/usr/bin/env python3` is a bug and it should be fixed. Best, Matěj -- http://matej.ceplovi.cz/blog/, @mcepl@floss.social GPG Finger: 3C76 A027 CA45 AD70 98B5 BC1D 7920 5802 880B C9D8 And do you know, Sonia, that low ceilings and tiny rooms cramp the soul and the mind? -- Fyodor Dostoevsky: Crime and Punishment
Hello, Am Dienstag, 10. Oktober 2023, 08:22:54 CEST schrieb Daniel Garcia:
%python3_fix_shebang
This macro expands to:
for f in /home/abuild/rpmbuild/BUILDROOT/%{NAME}-%{VERSION}- %{RELEASE}.x86_64/usr/bin/*; do
I like the idea, but - what about python executables in /usr/sbin/, for example the AppArmor utils (aa-logprof etc.), firewalld, iotop, ...? Regards, Christian Boltz -- Now I hope the best for my seven 1.44MB disks, oh yes, very old ... and I feel about 8 years younger by copying files to disks. [Thomas Porschberg in opensuse]
On mar, 2023-10-10 at 22:30 +0200, Christian Boltz wrote:
Hello,
Am Dienstag, 10. Oktober 2023, 08:22:54 CEST schrieb Daniel Garcia:
%python3_fix_shebang
This macro expands to:
for f in /home/abuild/rpmbuild/BUILDROOT/%{NAME}-%{VERSION}- %{RELEASE}.x86_64/usr/bin/*; do
I like the idea, but - what about python executables in /usr/sbin/, for example the AppArmor utils (aa-logprof etc.), firewalld, iotop, ...?
That's solved in the latest version of the macros [1] [1] https://github.com/openSUSE/python-rpm-macros/pull/162/files -- Daniel García Moreno Python Packager
participants (8)
-
Axel Braun
-
Ben Greiner
-
Christian Boltz
-
Daniel Garcia
-
Dirk Müller
-
Lubos Kocman
-
Manfred Hollstein
-
Matěj Cepl