home / skills / letsrevel / revel-backend / updating-deps

updating-deps skill

/.claude/skills/updating-deps

This skill helps you update Python dependencies with UV, scan for outdated and unused packages, and safely edit pyproject.toml while preserving Django LTS.

npx playbooks add skill letsrevel/revel-backend --skill updating-deps

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
2.9 KB
---
name: updating-deps
description: Update Python dependencies using UV. Scan for outdated packages, identify unused dependencies, and safely update pyproject.toml while respecting version constraints (e.g., Django LTS).
allowed-tools: Bash(uv:*), Bash(pip:*), Bash(make:*), Read, Grep, Edit
---

# Dependency Update Workflow

A structured approach for updating Python dependencies in this UV-managed project.

## Prerequisites

- This project uses **UV** for dependency management (never pip directly)
- Dependencies are in `pyproject.toml` under `[project] dependencies` and `[dependency-groups] dev`
- Django is pinned to 5.2.x LTS (`>=5.2.x,<6.0`)

## Step 1: Check Outdated Dependencies

```bash
uv pip list --outdated
```

This shows all outdated packages. Focus on **top-level dependencies** listed in `pyproject.toml`.

## Step 2: Identify Unused Dependencies

For each suspicious dependency, search for actual usage:

```bash
# Check for imports
grep -r "from <package>|import <package>" src/

# Check if it's a transitive dependency
uv pip show <package> | grep -i "required-by"
```

### Known Transitive Dependencies (safe to remove from explicit deps)

These are pulled in automatically by other packages:
- `multidict` - transitive from aiohttp/aiogram
- `pygments` - transitive from mkdocs-material, pytest

### Type Stubs Belong in Dev

Move `types-*` packages to `[dependency-groups] dev`, not production dependencies.

## Step 3: Categorize Updates

### Safe Updates (patch/minor, no breaking changes)
- Patch versions: `1.2.3` → `1.2.4`
- Minor versions with good release notes: `1.2.x` → `1.3.x`

### Needs Review (major versions)
- Major bumps: `1.x` → `2.x`
- Check release notes/changelog before updating

### Version-Pinned Dependencies
- **Django**: Keep at latest 5.2.x LTS (`>=5.2.x,<6.0`)
- Check classifier in pyproject.toml: `"Framework :: Django :: 5.2"`

## Step 4: Apply Updates

Edit `pyproject.toml` directly, then sync:

```bash
uv sync --dev
```

## Step 5: Verify

Run all checks to ensure nothing broke:

```bash
make check
```

This runs: format, lint, mypy, i18n-check

## Common Patterns

### Remove Unused Dependency
1. Search for usage: `grep -r "import <pkg>" src/`
2. Check reverse deps: `uv pip show <pkg> | grep Required-by`
3. Remove from pyproject.toml
4. Run `uv sync --dev`

### Move to Dev Dependencies
1. Remove from `[project] dependencies`
2. Add to `[dependency-groups] dev`
3. Run `uv sync --dev`

### Pin to Major Version
```toml
# Allow patches within LTS
"django>=5.2.11,<6.0"
```

## Dependencies Removed (2026-02-04)

For reference, these were removed as unused/transitive:
- `django-extension` - typo (django-extensions already present)
- `django-money` - unused
- `freezegun` in prod - duplicate (already in dev)
- `multidict` - transitive from aiohttp
- `ninja-schema` - unused
- `pyopenssl` - unused
- `pygments` - transitive from dev deps
- `types-tqdm` - moved to dev
- `piexif` - moved to dev (only used in tests)

Overview

This skill updates Python dependencies for a UV-managed Django backend. It scans for outdated packages, detects unused or transitive dependencies, and safely updates pyproject.toml while preserving important version constraints such as Django 5.2 LTS. The goal is predictable, reviewable dependency changes and a verified sync with uv.

How this skill works

It lists outdated packages via uv and limits focus to top-level entries in pyproject.toml. It searches the codebase for imports to detect unused libraries and checks whether a package is only a transitive dependency. Recommended edits are applied directly to pyproject.toml and brought into the environment with uv sync, followed by the project verification tasks.

When to use it

  • Routine dependency maintenance (patch/minor updates)
  • Before a release or CI pipeline update
  • When dependencies are flagged as unused or transitive
  • When preparing to upgrade a major dependency (requires review)
  • After adding or removing packages to ensure a clean sync

Best practices

  • Use uv commands exclusively; never install with pip directly in this project.
  • Prioritize top-level deps listed under [project] dependencies and [dependency-groups] dev.
  • Treat types-* packages as dev-only and move them to the dev group.
  • Pin frameworks with LTS constraints (e.g., Django >=5.2.x,<6.0) and check pyproject classifiers.
  • Categorize changes: apply patch/minor updates automatically, review major version bumps with changelogs.
  • Run make check after sync to validate formatting, linting, typing, and i18n checks.

Example use cases

  • Run uv pip list --outdated and update several patch and minor versions, then uv sync --dev and make check.
  • Find a package that appears unused: grep the repo for imports, confirm it is transitive with uv pip show, then remove it from pyproject.toml and sync.
  • Move a types- or test-only package from production dependencies into [dependency-groups] dev, sync, and rerun tests.
  • Encounter a major bump for a core library: pin the current LTS range, review release notes, test in a feature branch before broad upgrade.

FAQ

How do I detect if a package is only transitive?

Search the code for imports and run uv pip show <package> to view Required-by. If other deps provide it and you find no direct imports, remove the explicit entry.

What if a major version is required?

Treat major bumps as needing manual review: read release notes, run tests in a branch, and ensure compatibility before editing pyproject.toml.

How do I keep Django on LTS?

Pin Django in pyproject.toml with a range like "django>=5.2.11,<6.0" and include the classifier "Framework :: Django :: 5.2" to signal the intended LTS target.