From Fedora Project Wiki

< SIGs‎ | Python

Revision as of 09:46, 9 July 2018 by Churchyard (talk | contribs)

Upgrading Python from 3.N-1 to 3.N

Here are the notes from upgrading Python form 3.6 to 3.7. Those are created to save us time next time when upgrading to 3.8. It is not a comprehensive guide, but if it once get to it, it'd be great.

Create a Change Proposal

Before anything can happen, we need to create a Change Proposal. Follow the normal procedure, get inspired by previous changes, but make sure the process haven't changed (copypasta is good, but check if the template hasn't been updated).

Create python3N package

This can happen as soon as the first alpha is released. If you have enough resources, try to do it even before. The python3X packages are designed to have flat/nonflat switches since Package-x-generic-16.pngpython36, so you will use this package once you want to update Package-x-generic-16.pngpython3.

Make a copr repo, bootstrap "important stuff" in it

Bootstrapping Python packages is nontrivial. Chances are high that form the upgrade to 3.N-1, the bootstrap sequence has changed, as more packages switched to python3-sphinx etc. Start as early as possible.

For 3.7, I've used rpm-list-builder. The yaml recipe is archived on my GitHub. It has some comments. Note that rpm-list-builder has limitations:

  • it doesn't bump releases, so you need to do that manually if you build one package once and the new build has new functionality (aka not just for tests)
  • the "continue form here" future isn't very useful for us and was designed for different purpose, so what i did is that most of the yaml was commented out and I was uncommenting sections that i needed keeping finished stuff above, TODO stuff at the botttom
  • everything is sequential. go do soemthing different form time to time

When Package-x-generic-16.pnggdb is updated in Fedora, you need to delete all Package-x-generic-16.pngpython3 builds from the copr repo, and bootsrap Package-x-generic-16.pnggdb - Package-x-generic-16.pngpython3 - Package-x-generic-16.pnggdb once more.

What wasn't done for 3.7 but might have been a good idea is to restart the procedure once in a while. Packages early in the bootstrap sequence were build once with alphas and never tested with betas and rc. I suggest to restart the procedure on beta1 and on rc1.

Preserving the yaml recipe is good, you can use it for Fedora later.

This is the command I've used:

rm work-directory/* -rf && rpmlb --download local --source-directory source-directory python37.yaml python37 --work-directory work-directory --build copr --copr-repo @python/python3.7

I had local fedpkg clones, so I could create quick hotfixes in them. Also a must for Package-x-generic-16.pngpython3 package - you have it updated to 3.N, but rawhide still has 3.N-1.

Once ready, move into Fedora proper

Ready can differ. For 3.7 it was when rc1 was released and all important stuff from the yaml recipe was built in copr (in fact, couple of packages were not, but the fix was known).

Request a side tag

Example: Side tag for Python 3.7 releng issue

You'll get a side tag name (target). It can differ. For 3.7 it was f29-python.

To build in the side tag, you do:

fedpkg build --target=<name>

To wait for builds to get into the repos, do:

koji wait-repo <name> --build=<nvr>

Reproduce the bootstrap sequence

Juts get the recipe and rebuild in the side tag. rpm-list-builder could not do it with 3.7 so I've used a dirty script. Be prepared for failures, packages got updated in the meantime and new deps were added. Tough life.

Rebuild everything else

Now this gets a bit magical but what I did is that I've used mini-mass-rebuild to rebuild everything. Remember to bump the release and use the side tag (the script needs to adjusted).

What is everything? First, i get the packages that buildrequire Package-x-generic-16.pngpython3-devel:

 dnf repoquery  --disablerepo='*' --enablerepo='rawhide-source' --whatrequires python3-devel

But I forgot the virtual provides:

dnf repoquery  --disablerepo='*' --enablerepo='rawhide' --provides python3-devel

Also a good idea what actually needs a rebuild is:

dnf repoquery --whatrequires '' --source
dnf repoquery --whatrequires 'python(abi) == 3.6' --source

Use 3.N-1 instead of 3.6.

A helpful pkgname command to pipe those things into:

import fileinput

for line in fileinput.input():

Remember that you already built stuff that doesn't need extra rebuild. To remove list of packages form list of packages, I use

python3 all_rawhide already_built remains

There are also and in mini-mass-rebuild.

parallel -j 32 bash ../ -- $(cat ../remains) | tee ../status
for i in free open closed failed canceled; do echo -e $i\\t$(grep " $i" ../status | wc -l); done
cat ../status | grep " closed" | cut -d" " -f1 | tee ../closed
python3 ../ ../remains ../closed ../remains


parallel -j 32 bash ../ -- $(cat ../remains) | tee ../reason
cat ../reason | grep ' build'  # FTBFS
 cat ../reason | grep ' root'   # missing dependency

It's a good idea to mass rebuild everything that remains until the number of closed (built) packages stops at 0. Don't forget not to bump the release over and over again. Later, start investigating the build failure reasons. Untangle any circular deps if found. Add them to yaml recipe for next time. File bugs. Cry.