fastapi - 💡(How to fix) Fix Static analysis commands are duplicated across lint.sh and pre-commit, making drift likely [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
fastapi/fastapi#15238Fetched 2026-04-08 01:40:14
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Author
Participants
Timeline (top)
converted_to_discussion ×1locked ×1

The recent change in PR #15136 adds ty check fastapi to scripts/lint.sh, but FastAPI now maintains the static-analysis command set in multiple places with slightly different entrypoints:

  • scripts/lint.sh
  • .pre-commit-config.yaml
  • .github/workflows/pre-commit.yml / CI setup

This creates a drift risk: each time a new checker is added or an existing one changes invocation details, contributors and automation may silently diverge.

Root Cause

Right now, ty is present both in scripts/lint.sh and in .pre-commit-config.yaml, but they are not driven from a single source of truth:

  • scripts/lint.sh runs bare executables:
    • mypy fastapi
    • ty check fastapi
    • ruff check ...
    • ruff format ... --check
  • .pre-commit-config.yaml runs the same tools through uv run ...

This means future updates can easily land in one path but not the others. PR #15136 is a good example of how easy it is for the maintenance burden to increase with every new tool added.

RAW_BUFFERClick to expand / collapse

Summary

The recent change in PR #15136 adds ty check fastapi to scripts/lint.sh, but FastAPI now maintains the static-analysis command set in multiple places with slightly different entrypoints:

  • scripts/lint.sh
  • .pre-commit-config.yaml
  • .github/workflows/pre-commit.yml / CI setup

This creates a drift risk: each time a new checker is added or an existing one changes invocation details, contributors and automation may silently diverge.

Why this matters

Right now, ty is present both in scripts/lint.sh and in .pre-commit-config.yaml, but they are not driven from a single source of truth:

  • scripts/lint.sh runs bare executables:
    • mypy fastapi
    • ty check fastapi
    • ruff check ...
    • ruff format ... --check
  • .pre-commit-config.yaml runs the same tools through uv run ...

This means future updates can easily land in one path but not the others. PR #15136 is a good example of how easy it is for the maintenance burden to increase with every new tool added.

Concrete risk

A contributor can get different results depending on whether they run:

  • bash scripts/lint.sh
  • prek run -a
  • the GitHub Actions pre-commit workflow

Even if they currently happen to pass, the repo is relying on humans to remember to update several places whenever the lint stack changes.

Suggested fix

Use one source of truth for the static checks. For example:

  1. Make .pre-commit-config.yaml call bash scripts/lint.sh (or smaller script fragments), or
  2. Make scripts/lint.sh invoke the exact uv run ... commands used by pre-commit, or
  3. Generate/centralize the command list so adding a new checker only requires one edit.

A smaller improvement would be to at least align invocation style between the script and pre-commit (uv run ... vs bare executables), so local and automated paths behave more consistently.

Context

This issue was noticed while reviewing the latest changes on master, specifically PR #15136 (👷 Add ty check to lint.sh).

extent analysis

Fix Plan

To address the issue, we will use a single source of truth for static checks. We'll make .pre-commit-config.yaml call bash scripts/lint.sh. Here are the steps:

  • Update scripts/lint.sh to include all static checks:
    #!/bin/bash
    mypy fastapi
    ty check fastapi
    ruff check ...
    ruff format ... --check
  • Update .pre-commit-config.yaml to call scripts/lint.sh:
    repos:
    - repo: local
      hooks:
      - id: lint
        name: Lint
        entry: bash scripts/lint.sh
        language: system
        types: [python]
  • Update .github/workflows/pre-commit.yml to call pre-commit run:
    name: Pre-commit
    on:
      push:
        branches:
          - main
    jobs:
    pre-commit:
      runs-on: ubuntu-latest
      steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Install pre-commit
        run: pip install pre-commit
      - name: Run pre-commit
        run: pre-commit run -a

Verification

To verify the fix, run the following commands and check for consistent results:

  • bash scripts/lint.sh
  • pre-commit run -a
  • GitHub Actions pre-commit workflow

Extra Tips

  • Use a consistent invocation style throughout the repository.
  • Consider generating the command list centrally to simplify adding new checkers.
  • Regularly review and update the static checks to ensure they remain consistent and effective.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING