# Fedora Loves Python 2020 report
Hello Fedorans and especially Pythonistas,
Inspired by a similar [report from the Copr team](https://firstname.lastname@example.org/thread/R2MWYN7CRF34WKSRUUYNLAISQB47MHXI/), I've decided to look back at 2020 from the perspective of Python in Fedora (and little bit in RHEL/CentOS+EPEL as well). Here are the things we have done in Fedora (and EL) in 2020. By *we* I usually mean the Python Maint team at Red Hat and/or the [Fedora's Python SIG](https://fedoraproject.org/wiki/SIGs/Python).
The year 2020 was a special year for the Python community (not only because of the pandemic), as Python 2 has finally gone out of support at the very beginning of the year, with an ultimate (somehow celebratory) [release of Python 2.7.18 in April](https://email@example.com/thread/OFCIETIXLX34X7FVK5B5WPZH22HXV342/).
## Rollin', rollin', rollin'
During the year, we've kept several Python versions in Fedora always up to date, and Python developers were able to test their software with Python 2.7.18, 3.5.10, 3.6.10–12, 3.7.7–9, 3.8.2–7, 3.9.0 alphas, betas and release candidates as well as 3.9.1 and early alphas of 3.10.0 as soon as they were released upstream, usually within one business day + mirror delays. (Including the release candidates of the bugfix releases on Rawhide.) Tomáš Hrnčiar created a [nightly-updated calendar with upstream Python release schedules](https://github.com/fedora-python/python-release-schedule-ical), which makes this much easier to track. We have also kept PyPy 2.7 and 3.6 as well as MicroPython up to date (although the response time is not that good there).
Since the process for keeping our Pythons up to date was only in my head, we have started to document most of the stuff to avoid problems if I'm hit by a bus. We now have a public forever-work-in-progress [guide about our Python (interpreters) maintenance in Fedora](https://hackmd.io/9f64YNIZTCy0ZzKb5wKtqQ). When documenting, we also identified stuff to automate and we managed to actually automate most of it, such as [importing our patches from GitHub](https://github.com/fedora-python/importpatches), [cherry-picking dist-git commits between different similar components](https://github.com/fedora-python/ferrypick), [automatically resolving simple git merge conflicts in %changelogs](https://github.com/encukou/rpm-spec-merge-driver/) and more.
When EPEL 6 went end of life, we have [retired Python 2.6](https://fedoraproject.org/wiki/Changes/RetirePython26) and [3.4](https://fedoraproject.org/wiki/Changes/RetirePython34) from Fedora 33+.
At the beginning of 2020, we have just successfully finished [migrating Fedora 32 to Python 3.8](https://fedoraproject.org/wiki/Changes/Python3.8) only to immediately start working on [Python 3.9 for Fedora 33](https://fedoraproject.org/wiki/Changes/Python3.9). This close followup was caused by [originally postponing Python 3.8 from Fedora 31 to 32](https://firstname.lastname@example.org/thread/PNIHDOJC2OYLJY5QXU6OPQAIKGCKSAB3/) in 2019 because the release schedules of Python and Fedora were a tad too misaligned to allow a safe upgrade so soon. We have managed to [align them better](https://email@example.com/thread/AKA3USBKFYKUQDSGDK4FNDYYWMKM7XKX/) late in 2019 which allowed us work on 3.9 starting in early 2020.
Due to the end of life of Python 2 in 2020, many Python 2 backwards-compatibility shims were removed from Python 3.9, causing a lot of new breakages in projects that have not yet managed to respond by removing Python 2 support, not because they would not want to, but simply because it happened too early. We've detected and measured the impact on Fedora packages and [managed to postpone the most breaking changes](https://firstname.lastname@example.org/thread/EYLXCGGJOUMZSE5X35ILW3UNTJM3MCRE/) to Python 3.10, giving the projects one more year to adapt.
Speaking of Python 3.10, we have started to work on the [Python 3.10 change for Fedora 35](https://fedoraproject.org/wiki/Changes/Python3.10) late in 2020, making it one of our primary tasks for 2021. If you maintain a Python package, you might have seen a bug report from us already. We test early and we test often to avoid sudden Rawhide breakage. As always, we don't only report, but we try to help as much as we can, but we cannot single-handedly fix hundreds of packages. Package maintainers are crucial to make this all work, so the thanks goes out to you!
During one year, we've obviously updated many crucial Python packages as well. I'd like to highlight a complicated [pipenv upgrade after two years of upstream development](https://fedoramagazine.org/come-test-a-new-release-of-pipenv-the-python-development-tool/).
## Continuous integration
As most of the Python interpreters (all but MicroPython) need setuptools and pip for the `venv` tool (that creates Python virtual environments) as well as for `virtualenv` and `tox`, we've made sure the new Python versions have an up to date version of setuptools and pip built in Fedora and the older ones use the bundled versions provided by upstream. In order to make sure everything works as expected, we were constantly improving our CI coverage: During an update of Python, setuptools, pip, virtualenv, tox and/or other important packages, automated tests ensure that everything keeps working as expected for Python developers running Fedora.
Apart form testing Python integration in Fedora, we have also broadened the testing matrix of Python's upstream CI, adding Fedora and RHEL buildbot workers for various architectures. The s390x machines were provided in cooperation with IBM Research, ppc64le machines were provided by OpenPower hub from Brno's Faculty of Information Technology, [ARM provided an aarch64 bare metal server](https://github.com/WorksOnArm/cluster/issues/191), and x86_64 machines were already in place. Currently the upstream CI tests CPython with various configurations: Fedora Rawhide, the latest stable Fedora, RHEL 7 and RHEL 8, and on all the architectures we support.
Being able to test upstream changes early on Fedora not only avoids potential problems in Python itself, but helped us to identify unrelated problems in the distro as well. Thanks to the upstream CI, we have discovered:
- [CVE-2020-9391 in aarch64 kernel](https://bugzilla.redhat.com/show_bug.cgi?id=1797052): regression in the `brk()` syscall manifested as a segfault in Python.
- Multiple issues related to GCC 10 in Rawhide including a [bug in GCC 10 itself (on ppc64le)](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93384).
- And several other issues in essential parts of Fedora.
We have also worked on extending the Fedora Python experience beyond developers' machines. It is now easier than ever to [run Python tests on Fedora using GtiHub Actions](https://github.com/marketplace/actions/python-tox-on-fedora). Give it a go, instead of the default Ubuntu, when setting an upstream CI.
In 2020, we have also significantly improved the automated testing of Python packaging RPM macros and dependency generators. Speaking of which…
## Python packaging improvements
Many interesting changes happened during 2020, changes not only targeted to developers and users, but also to Fedora's Python package maintainers: The overall number of Python packages in Fedora has grown from ~3150 to ~3900 since Fedora 31 was released late in 2019. They currently constitute ~17% of all Fedora packages. Over 700 different people (unique by email addresses, obvious duplicates and bots removed) have committed to those packages in 2020. Thank you all!
We have significantly [improved the Python RPM dependency generators](https://email@example.com/thread/SSJLPWSGFGPYRSHXQZDR7JNQXSDGGX3Z/), we have introduced the [`%py_provide`](https://firstname.lastname@example.org/message/6DGWPIRP7AYBZP5XEB67YP263P6Q6WTB/), [`%pytest`](https://email@example.com/message/XLPDSH362PJKMJCAYOXNJNV53Y66EF6B/), [`%python3_shebang_fix`](https://src.fedoraproject.org/rpms/python-rpm-macros/pull-request/58) macros, we have [introduced a way to create more reproducible Python bytecode](https://docs.fedoraproject.org/en-US/packaging-guidelines/Python_Appendix/#_byte_compilation_reproducibility) with a [new tool](https://github.com/fedora-python/marshalparser/) written just for that purpose. But the biggest new development in Python RPM packaging was finally [adding the ability to package Python extras](https://fedoraproject.org/wiki/Changes/PythonExtras). Most of this was backported to EPEL (or at least we made sure the usage of these new features in an EPEL specfile does not fail the build).
Several small [changes](https://pagure.io/packaging-committee/pull-request/940) were made to the [Fedora's Python packaging guidelines](https://docs.fedoraproject.org/en-US/packaging-guidelines/Python/) in 2020, while we have [continuously worked to present a completely revised guidelines and macros](https://firstname.lastname@example.org/thread/ZCNUQBJLDUJUJXK2EOPP2MWL6FJKLBPS/) in 2021. We have also significantly improved the [pyproject-rpm-macros](https://src.fedoraproject.org/rpms/pyproject-rpm-macros), adding support for more complex cases and even new features, most importantly the automatic `%files` section. Give it a try in 2021 if you haven't yet. Close to one hundred packages already use them, most of them started in 2020.
## Improving Python for everybody
In April, [Phoronix reported Python is a lot faster in Fedora 32](https://www.phoronix.com/scan.php?page=article&item=fedora-32-benchmarks&num=5) -- this was [achieved by using `--no-semantic-interposition`](https://fedoraproject.org/wiki/Changes/PythonNoSemanticInterpositionSpeedup). The flag is now the default for Python in upstream, thanks to integration testing in Fedora.
For 16 years, Fedora was patching Python to install to `/usr/lib64` on 64-bit systems. Similar patch was present in openSUSE, Debian, Gentoo and many other distros. In 2020, we have finally managed to [merge it upstream](https://github.com/python/cpython/commit/8510f430781118d9b603c3a2f06945d6ebc5fe42)! (Though credit where credit's due, the code was contributed both by Fedora and openSUSE folks.)
Early in 2020, we have [explored some options to minimize the filesystem footprint of Python](https://github.com/hroncok/python-minimization/blob/master/document.md), to match with the Fedora's Minimization objective. Unfortunately, [there has not been much response from upstream](https://discuss.python.org/t/disk-space-minimization-for-python-distributors/5447/8) and we have not finished much on this front yet. However, some small adjustments were made in downstream packaging, for example [only shipping some of the large automatically generated modules as bytecode](https://src.fedoraproject.org/rpms/python3.9/pull-request/16), saving 2+ MiB. We've also [added a hardlink deduplication flag for the bytecode compiling tool](https://discuss.python.org/t/compileall-option-to-hardlink-duplicate-optimization-levels-bytecode-cache-files/3014), mimicking the [already existent buildroot policy script](https://github.com/rpm-software-management/rpm/blob/master/scripts/brp-python-hardlink) that [originated in Fedora 13 years ago](https://src.fedoraproject.org/rpms/redhat-rpm-config/c/a959c1f92d55d1829a6b1c3d45d765d8a4129551?branch=master).
## On the RHEL (and CentOS) side
The [Python 3.8 module has been added to RHEL 8](https://developers.redhat.com/blog/2020/06/25/red-hat-enterprise-linux-8-2-brings-faster-python-3-8-run-speeds/) and we are working on Python 3.9 as well. If all goes well, you should be able to check it out in the new CentOS Stream even before it's released in RHEL 8. We have also been [preparing Fedora to allow packaging parallel-installable Python stacks with non-modular RPMs](https://bugzilla.redhat.com/show_bug.cgi?id=1821489) trying to provide an even better experience in RHEL 9. The [Python 3.8 Software Collection](https://developers.redhat.com/blog/2020/05/29/red-hat-software-collections-3-5-brings-updates-for-red-hat-enterprise-linux-7/) was added for RHEL 7.
The `--no-semantic-interposition` speedup was backported to the (Platform) Python 3.6 interpreter as well as Python 3.8 in RHEL 8. [FIPS](https://en.wikipedia.org/wiki/Federal_Information_Processing_Standards) support has been overhauled and implemented on RHEL 8 for Python 3.6 and 3.8, various related fixes have been merged upstream. Many CVEs affecting Python and relevant components have been fixed across various RHEL products.
## Honorable mentions
* The [IDLE](https://docs.python.org/3/library/idle.html) icon was introduced many many years ago in Python 2.5. While working on the [Fedora Python Classroom Lab](https://labs.fedoraproject.org/en/python-classroom/), I've realized the 48×48px icon looks really bad in GNOME Shell, and so in 2020 we have managed to dig out [the original sources](https://www.doxdesk.com/software/py/pyicons.html), and now the icon displayed in GNOME is 256×265px. We also have a scalable SVG (converted from an ancient proprietary format while we still had the option).
![The IDLE icon is no longer hideous](https://i.imgur.com/t2YUAZT.png)
* The [S2I Python container](https://github.com/sclorg/s2i-python-container) with Python 3.9 based on Fedora 33 is now available.
* We have managed to get rid of a slight difference in architecture naming between upstream Python and Fedora, [which looked innocent when introduced long time ago, but turned out to be a phantom menace](https://fedoraproject.org/wiki/Changes/Python_Upstream_Architecture_Names#The_Saga).
* The names of Python packages in Fedora that don't exist on Python Package Index [have been blocked on PyPI](https://github.com/pypa/pypi-support/issues/355) to prevent malicious attempts and/or random conflicts. If you maintain such package, please encourage upstream to publish it on PyPI (they need to [let us know first](https://github.com/pypa/pypi-support/issues/355#issuecomment-655738640) to be able to do that).
## What's next?
In 2021, we'll try to keep up with 2020 and ensure Fedora is the best operating system for a Python developer.
The priorities of our team for the upcoming months (apart from constant backporting of CVE fixes to an *n*-dimensional matrix of components) are the Python 3.9 module for RHEL 8, Python 3.10 in Fedora 35 (and 3.11 for 37, huh, that sounds very far away, but fits into 2021), more RHEL 9 work, finally proposing [the new Python guidelines](https://email@example.com/thread/ZCNUQBJLDUJUJXK2EOPP2MWL6FJKLBPS/) and possibly creating a new spec file generator that leverages the pyproject macros. We might end up working on the filesystem footprint minimization.
I'd like to add even more complex CI tests to Fedora (e.g. *when I upgrade pytest, what's the impact on all packages that use it*). If there is high enough demand, I might look into adding [Python 3.9 to EPEL 7](https://bugzilla.redhat.com/show_bug.cgi?id=1781940#c11) (only the interpreter, not a parallel stack) to supplement the RHEL 8 module and the main Python version in ELN.
However, most of the cool stuff from 2020 happened without a year-long planning. So as always, I expect we'll just have to wait and see.
(Big thanks to the team for helping me write this article.)