Python3: Out with the old, in with the new
Oh, happy day! I truly do enjoy Python version bumps. With Python 2 at EOL, and Gentoo Linux making big moves over the past couple of months to bump the Python3 default target to Python 3.7, it has been a very exciting time for me to be working so much with Python. Though a bit confusing at times, the care and attention put in by the Gentoo Python Team has made this an easier transition to go through.
diff gentoo
As part of my usual morning routine, one of the first things I check on the
computer is a diff
of the changes introduced to the Gentoo package
repositories since my last sync 1. Honestly, it’s a great way to start the
day for me. I highly recommend the eix utility for much quicker package
searching than Portage allows for, if nothing else.
Anyway, the point of that mention — this morning I noticed Python 3.8 had
been bumped to stable on amd64
. Finally! I couldn’t quite determine if this
was intended to be another slotted version, or if it would coincide with other
updates to the Gentoo Python ecosystem. Checking a bit deeper into this now,
I noticed a news item, Python 3.7 to become the default target.
Wow! This is getting exciting! Reading through that was initially a bit
confusing, but it really made my day. Being that it’s a weekday, I did have to
put that on hold and head to work. It did give me an opportunity to read over
the news item a bit more, and consider how to handle this update. With Python
being just a bit integral to Gentoo, I have decided to not rush into this,
and let Portage do what it wants to do. For me, this means simply accepting
the update without modifying either of the PYTHON_{TARGETS,SINGLE_TARGET}
values. At this moment, if you are using the default targets, no further action
is required at this time. Simply emerge -uDNatv @world
as usual, and carry
on. For me, the only Python related change there was pulling in version 3.8 as
it is now marked stable. At least on amd64
that is.
What if I don’t want to wait?
Two weeks is quite a long time away, I know. Thankfully, you can go ahead with the migration, if you like. How cleanly, or painfully this may happen will somewhat depend on the packages installed to your system which utilize Python 3.6 as their default target. If you utilize any services, or daemons that target that version, you may wish to apply the update in parts, described below. Alternatively, if those programs can be stopped during the update, it may help ensure no errors occur. The news post linked here does mention that already loaded & running programs should not encounter errors during this update. However, if they are restarted or load additional modules during this process, there may be errors. If you do keep them running during the update, you will need to restart them after it has completed so they can load up again using the new Python 3.7 target they will have been rebuilt for. My personal recommendation is to apply the update in parts to minimize any risk of breakage to currently running programs.
How do we do this?
The news item lists out all of the relevant steps, and should provide ample information to proceed without any major issues. The processes laid out below come from that news item, with my own thoughts. Three different scenarios are described below
Update all at once
So long as you have not overridden either PYTHON_{TARGETS,SINGLE_TARGET}
on
your system, the update should happen “When It’s Ready™”. This is expected to be
on, or after May 05, 2020 as per the Gentoo News item. Simply stay on top
of your regular system updates and it will happen on it’s own. Once it does
happen, you will want to clean up any stray packages with commands such as:
The depclean
command has the the potential to remove important packages
from your system. Always check the list of packages to remove before
proceeding. If you are uncertain and cannot determine on your own, ask or
skip over it, leaving the package in question installed.
emerge --depclean --ask emerge -1vUD --ask @world emerge --depclean --ask
Now may be a good time to update your default Python version as well
$ eselect python list Available Python interpreters, in order of preference: [1] python3.6 [2] python3.8 (fallback) [3] python3.7 (fallback) [4] python2.7 (fallback) $ sudo eselect python set 3
This series of commands will check Portage for any packages which are no
longer required, based on the dependency tree. Then update any packages which
have had changed USE
flags (such as PYTHON_TARGETS
), while taking the
entire dependency tree into account. Finally, a last --depclean
to clear
out any new packages which may no longer be required. This should leave your
system with packages rebuilt to prefer Python 3.7 whenever possible. Any
packages installed in the future will follow those new defaults as well.
If you would like to improve the stability of the upgrade, use the steps outlined below instead.
Update in stages
Temporarily enabling both Python 3.6 and Python 3.7 targets may improve
stability of the upgrade. This will cause the dependencies effected by the
update to build with support for both versions wherever possible. The file
edited to enable both Python targets will depend on whether you have a file, or
a directory at /etc/portage/package.use
. If there is a file at that path,
edit it with the following values. If there is a directory at that path, edit a
new file with a name such as /etc/portage/package.use/python-targets
:
*/* PYTHON_TARGETS: python3_6 python3_7 */* PYTHON_SINGLE_TARGETS: -* python3_6
With those two lines added, you should proceed with the first stage of the update. This will rebuild packages with additional support for Python 3.7 where applicable, without removing any Python 3.6 support yet.
The depclean
command has the the potential to remove important packages
from your system. Always check the list of packages to remove before
proceeding. If you are uncertain and cannot determine on your own, ask or
skip over it, leaving the package in question installed.
emerge --depclean --ask emerge -1vUD --ask @world emerge --depclean --ask
Take the time now to restart any running scripts, daemons, or programs that were
included in that update list. Then either comment out, or delete the two lines
previously added into your /etc/portage/package.use
. You may also want to
update your default Python version at this time through the eselect
command:
$ eselect python list Available Python interpreters, in order of preference: [1] python3.6 [2] python3.8 (fallback) [3] python3.7 (fallback) [4] python2.7 (fallback) $ sudo eselect python set 3
The final step here is to re-apply the update. This time only Python 3.7 support will be built, where applicable. Certain packages may not yet have been updated to support Python 3.7. In these cases, the Gentoo Python Team is working to push out the updates in time. For those reasons, not every package will rebuild into Python 3.7 support right away. As mentioned in the beginning of this section, pay attention to the `depclean` command — it can remove important system packages!
emerge --depclean --ask emerge -1vUD --ask @world emerge --depclean --ask
Finally! This all complete, you should be finished up now. Your Gentoo system should now be using Python 3.7 as the default version. Packages should have been rebuilt to prefer Python 3.7 over other versions, where possible. And packages built in the future will follow in that preference.
Postpone the update
Should you not wish to update the system default Python target for whatever
reason, you can simply block the target. This will prevent Portage from
attempting to build that target, using Python 3.6 instead as it does
currently. The file edited to enable both Python targets will depend on whether
you have a file, or a directory at /etc/portage/package.use
. If there is a
file at that path, edit it with the following values. If there is a directory
at that path, edit a new file with a name such as
/etc/portage/package.use/python-targets
:
*/* PYTHON_TARGETS: -python3_7 python3_6 */* PYTHON_SINGLE_TARGETS: -* python3_6
Should you decide to go ahead with the update in the future, comment out or remove those two lines. Then proceed as described above, or in the main Gentoo News item here.
In conclusion
With Python 3.6 no longer receiving bug fixes, and will be approaching it’s
own end-of-life just before Christmas of 2021, it is a good time to update.
Enjoy the added features such as nanosecond timers in the time
module, or
Data Classes. Lots more details at official What’s new in Python 3.7 page.
Whether you update all at once, next year, or jump straight to Python 3.8,
it is important to keep your system regularly updated. This guide was written
to help facilitate that, and assist any other Gentoo Linux users who find
themselves uncertain on how to proceed.
Footnotes
- 1
-
To create, and check the repo
diff
, I utilize theeix
utility, in combination with Portage’spostsync
hook. The method I used to set this up is on this Gentoo Wiki page. This utility has become almost essential to me as I want to know exactly what changed throughout the repos.