SuperAPI AI Directory

python-upgrade-package

Coding & development

View repository

Updated 10-16 05:01

About this skill

python-upgrade-package

Upgrade one or more Python packages with uv, by assessing the real impact of the upgrade on the project before applying it, then validating it through tests. $ARGUMENTS = the packages to upgrade (and, if specified, the target version of each).

The risk is the breaking change that goes unnoticed. This skill therefore enforces the order:

  • understand what changes
  • check whether the project uses it
  • apply
  • prove that it holds.

Workflow

Copy this checklist into the response and tick it off as you go:

- [ ] 1. Cadrer     : lister les paquets, version courante → cible, pin exact vs plage
- [ ] 2. Changelogs : prévisualiser les co-montées, puis lire les entrées entre courant et cible, extraire les cassures
- [ ] 3. Impact     : confronter chaque changement cassant à l'usage réel dans le code
- [ ] 4. Décision   : impact → corriger dans la foulée ou s'arrêter ; sinon continuer
- [ ] 5. Appliquer  : la montée via uv
- [ ] 6. Lock       : git diff uv.lock — vérifier ce qui a bougé
- [ ] 7. Tests      : suite de tests + test de démarrage si binaire de service
- [ ] 8. Audit      : uv audit --frozen (si la montée visait une CVE)
- [ ] 9. Rapport    : synthèse + indexer pyproject.toml et uv.lock (ne pas commiter)

Steps 2 to 4 are repeated per package ; step 5 applies them together.

Delegation. When several packages are to be analyzed (requested + sensitive co-upgrades identified by the dry-run), launch in a single message a subagent Agent (subagent_type=general-purpose) per package, each with the prompt references/analyse-paquet.md filled in (package, versions, project root, role). Each agent returns the compact table defined in the prompt — never a massive copy-paste. A single package with no co-upgrade → do steps 2–3 inline, without a subagent. In all cases, step 4 and the following ones remain in the main conversation.

1. Frame

First gather the information that will be used later.

  • Current version : read pyproject.toml (constraint) and uv.lock (locked version). If in doubt: uv tree --package <pkg>.
  • Target version : from $ARGUMENTS. Not specified or "latest" → latest stable.
  • Form of the constraint : exact pin (pkg==X) or range (pkg>=X, >=X,<Y) — this changes the mechanics (step 5).

2. Changelogs

First, list the co-upgrades. An upgrade often pulls in other packages (raised minimum bounds, shared dependencies). Preview the resolution before any reading of changelogs:

  • exact pin: uv add --dry-run 'pkg==Y' (with extras if any) ;
  • range: uv lock --dry-run --upgrade-package pkg.

Identify all the packages that would move. Each co-upgrade of a sensitive package (server, worker, ORM, crypto, serialization, any package imported by the code) follows steps 2 to 4 just like the requested packages — not just a check afterwards.

For each package, read only the entries strictly between the current version (excluded) and the target (included). For a jump of several major versions, accumulate the breakages of each stage.

  • Find the source: PyPI page https://pypi.org/project/<pkg>/ → project links → GitHub Releases, CHANGELOG.md / CHANGES.rst. WebFetch on these URLs; WebSearch "<pkg> <cible> changelog breaking changes" as a complement.
  • Identify and note: Breaking / Removed / Deprecated / Backwards incompatible, changed default values, modified signatures, increase in the minimum required Python version.
  • Ignore the rest (features, performance, internal fixes): only what can break the project matters here.

3. Impact on the project

For each breaking change identified, check whether the project actually uses the affected API — do not assume.

  • git grep -n "<symbole|import|api>" on the code (imports, calls, subclasses).
  • Do not forget: config files, CLI options, configuration keys, entry points / [project.scripts].
  • Classify each break: affected (to be handled) or not affected (no effect here).

4. Decision

  • No impact → continue.
  • Impact → never upgrade the version while breaking things silently. Two options, depending on the scope:
    • small and directly related → fix the code in the same task;
    • large or uncertain → stop and ask how to proceed (AskUserQuestion).

5. Apply (uv mechanics)

  • Exact pin pkg==X — recommended: uv add 'pkg==Y' (updates the constraint in pyproject.toml, relocks and synchronizes in a single command). Keep the extras: uv add 'pkg[extra]==Y'. Several at once: uv add 'a==1' 'b==2'.
  • Range pkg>=X — upgrade within the range without touching the constraint: uv lock --upgrade-package pkg then uv sync. To go beyond the upper bound: edit the constraint (or uv add) then relock.
  • Do not run uv lock --upgrade (without --package) unless explicitly requested: it upgrades the entire graph.

6. Check the lock

git diff uv.lock : confirm that the diff matches the co-upgrades planned in step 2 — nothing more. Any package that moves without having been planned goes back to step 2.

7. Tests + smoke test

  • Run the test suite of the project following the best practices defined in the project.
  • Target first the modules that use the package, then expand.
  • If the package provides a service binary (WSGI/ASGI server, worker, CLI), add a smoke test, a successful import does not prove that the service starts.

8. Audit (if CVE)

When the upgrade was aimed at a vulnerability: uv audit --frozen and confirm that the package has left the report.

9. Report

Compact summary, one table per batch:

Package Current → Target Breaking changes Project impact Tests

Then index pyproject.toml and uv.lock (git add). Do not commit : it is the maintainer's decision; one upgrade (or one coherent batch) = one commit.

Safeguards

  • The order changelog → impact → application is not negotiable: applying first means discovering the breakage in production.
  • A silent upgrade that breaks a used API is a failure, not a time saver.
  • Never upgrade the entire graph (uv lock --upgrade) for convenience.