Skip to content

Bump django-stubs from 6.0.7 to 6.1.0 - #2265

Merged
JSv4 merged 5 commits into
mainfrom
dependabot/pip/django-stubs-6.1.0
Aug 30, 2026
Merged

JSv4 merged 5 commits into
mainfrom
dependabot/pip/django-stubs-6.1.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 19, 2026

Copy link
Copy Markdown
Contributor

Bumps django-stubs from 6.0.7 to 6.1.0.

Commits

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [django-stubs](https://github.com/typeddjango/django-stubs) from 6.0.7 to 6.1.0.
- [Release notes](https://github.com/typeddjango/django-stubs/releases)
- [Commits](typeddjango/django-stubs@6.0.7...6.1.0)

---
updated-dependencies:
- dependency-name: django-stubs
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file python Pull requests that update Python code labels Aug 19, 2026
@claude

claude Bot commented Aug 19, 2026

Copy link
Copy Markdown

Review Summary

This is a routine Dependabot bump of django-stubs from 6.0.7 → 6.1.0 in requirements/local.txt — a dev-only type-stubs package, no production code affected. Single-line diff, low risk.

Code quality / best practices: N/A — pure version pin bump, follows the existing pinning convention (== with a source comment link).

Potential bugs: None expected from the stubs bump itself, but per the changelog this release includes "Support custom arguments in queryset update methods" and "Explicit through default manager" — these change how mypy type-checks certain Django ORM patterns (.update() with custom manager args, M2M through models). Worth running mypy (or the pre-commit hook that wraps it) locally to confirm no new type errors surface in code that relies on those patterns.

Performance: No runtime impact — stubs are type-check-time only, not shipped in production.

Security: No security concerns; this is a well-known, actively maintained typeddjango project.

Test coverage: N/A for this change. Recommend letting CI (which runs pre-commit/mypy) confirm the bump is clean before merging, per this repo's baseline commit rule of "make sure typescript compiles and pre-commits pass before committing new code" (analogous mypy check applies here).

Safe to merge once CI is green.

JSv4 added a commit that referenced this pull request Aug 20, 2026
…ired

`main`'s branch protection has no `required_status_checks` object at all, so
nothing gates a merge on CI having run, let alone passed. PR #2262 merged with
Backend CI never having run on its head commit at all -- and because nothing
was required, "no check reported" was not a blocker. The push that merged it
then failed at the linter, which skipped `pytest` (0s); `main` sat that way for
~30 hours, repaired only by accident when an unrelated PR's
`pre-commit run --all-files` happened to reformat the same file.

Requiring *something* is therefore the fix, but requiring the `pytest` job is
not, because it leaves a second hole open and opens a third:

  * GitHub reports a job skipped by its own `if:` as SUCCESS to branch
    protection. `pytest` is gated on `needs.linter.result == 'success'`, so a
    red linter skips it and a required `pytest` still reads green. This is not
    hypothetical: PRs #2260, #2264 and #2265 are all sitting at
    `linter=failure / pytest=skipped` right now, and would be mergeable under
    that policy with a red linter.
  * A workflow skipped by path filtering never reports its checks at all, so
    the required check hangs Pending forever. With `paths-ignore: docs/**` on
    the `pull_request` trigger, requiring any job here would make docs-only
    PRs permanently unmergeable.

So the requirable check has to always run and inspect the other jobs itself,
telling "skipped because this PR touches no backend code" apart from "skipped
because something upstream broke". That is the new `gate` job; its decision
table is `.github/scripts/backend_ci_gate.sh`, which carries a `--self-test`
that the job runs on every invocation -- a gate whose own logic has silently
inverted is worse than no gate.

`paths-ignore` is dropped from the `pull_request` trigger for the reason
above; the `changes` path filter still keeps the expensive jobs from running,
so a docs-only PR now costs two ubuntu-latest jobs of a few seconds.

`require_backend_ci_gate.sh` applies the protection change itself, because the
obvious `gh api` call is a footgun: `PUT .../branches/main/protection` replaces
the ENTIRE object (dropping review rules and the force-push/deletion bans
unless they are re-sent), and the narrower
`PATCH .../protection/required_status_checks` sub-resource 404s when no such
object exists yet. It refuses to require a context name that has never been
reported on the branch, since that would block every PR with no error anywhere.

Verified by replaying the gate over the last 60 Backend CI runs: it blocks all
8 PR runs with a red linter and both of the merge-commit runs from #2262's
window, and allows all 25 genuinely green runs and the 3 with no backend
changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
JSv4 added a commit that referenced this pull request Aug 20, 2026
…ired

`main`'s branch protection has no `required_status_checks` object at all, so
nothing gates a merge on CI having run, let alone passed. PR #2262 merged with
Backend CI never having run on its head commit at all -- and because nothing
was required, "no check reported" was not a blocker. The push that merged it
then failed at the linter, which skipped `pytest` (0s); `main` sat that way for
~30 hours, repaired only by accident when an unrelated PR's
`pre-commit run --all-files` happened to reformat the same file.

Requiring *something* is therefore the fix, but requiring the `pytest` job is
not, because it leaves a second hole open and opens a third:

  * GitHub reports a job skipped by its own `if:` as SUCCESS to branch
    protection. `pytest` is gated on `needs.linter.result == 'success'`, so a
    red linter skips it and a required `pytest` still reads green. This is not
    hypothetical: PRs #2260, #2264 and #2265 are all sitting at
    `linter=failure / pytest=skipped` right now, and would be mergeable under
    that policy with a red linter.
  * A workflow skipped by path filtering never reports its checks at all, so
    the required check hangs Pending forever. With `paths-ignore: docs/**` on
    the `pull_request` trigger, requiring any job here would make docs-only
    PRs permanently unmergeable.

So the requirable check has to always run and inspect the other jobs itself,
telling "skipped because this PR touches no backend code" apart from "skipped
because something upstream broke". That is the new `gate` job; its decision
table is `.github/scripts/backend_ci_gate.sh`, which carries a `--self-test`
that the job runs on every invocation -- a gate whose own logic has silently
inverted is worse than no gate.

`paths-ignore` is dropped from the `pull_request` trigger for the reason
above; the `changes` path filter still keeps the expensive jobs from running,
so a docs-only PR now costs two ubuntu-latest jobs of a few seconds.

`require_backend_ci_gate.sh` applies the protection change itself, because the
obvious `gh api` call is a footgun: `PUT .../branches/main/protection` replaces
the ENTIRE object (dropping review rules and the force-push/deletion bans
unless they are re-sent), and the narrower
`PATCH .../protection/required_status_checks` sub-resource 404s when no such
object exists yet. It refuses to require a context name that has never been
reported on the branch, since that would block every PR with no error anywhere.

Verified by replaying the gate over the last 60 Backend CI runs: it blocks all
8 PR runs with a red linter and both of the merge-commit runs from #2262's
window, and allows all 25 genuinely green runs and the 3 with no backend
changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
JSv4 pushed a commit that referenced this pull request Aug 30, 2026
djangorestframework-stubs 3.18.0 declares django-stubs>=6.0.9, but
requirements/local.txt pinned django-stubs==6.0.7. That made the dev/test
image unbuildable: the Dockerfile's `pip wheel -r requirements/local.txt`
step (compose/local/django/Dockerfile:58) aborted with

    ERROR: Cannot install -r ./requirements/local.txt (line 15) and
    django-stubs==6.0.7 because these package versions have conflicting
    dependencies.
    ResolutionImpossible

which is why the redis-integration job failed on this PR while the other
checks only skipped.

6.1.0 is the version already proposed by #2265, so the two bumps land on the
same pin rather than fighting over it.
@claude

claude Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review

This is a routine Dependabot dependency bump: django-stubs 6.0.7 → 6.1.0 in requirements/local.txt, a single-line diff.

Assessment:

  • Code quality / best practices: N/A — no application code changes, just a dev-dependency version bump.
  • Bugs: None expected. django-stubs is a mypy type-stub package used only for static type checking in local/dev environments; it has no runtime impact on the Django app, GraphQL schema, or frontend.
  • Performance: No effect — dev-only tooling dependency.
  • Security: This is a minor version bump (semver-minor per the PR metadata) from a well-known, actively maintained package (typeddjango/django-stubs). No security concerns.
  • Test coverage: N/A for this change. The only meaningful thing to verify is that mypy/type-checking still passes cleanly with the new stubs version, since minor stub releases occasionally tighten or change type signatures (e.g. the changelog for 6.1.0 mentions "Support custom arguments in queryset update methods" and "Explicit through default manager" — both could subtly change inferred types in code that uses QuerySet.update() with custom kwargs or M2M through managers).

Recommendation: Safe to merge once CI (including any mypy/type-check step, if one runs in this repo's pipeline) passes. No manual action needed beyond that.

claude added 2 commits August 30, 2026 03:34
The linter job on this PR fails with 10 I001/I005 findings in
opencontractserver/llms/agents/pydantic_ai_agents.py and
opencontractserver/utils/compact_pawls.py — files this PR does not touch. The
failure reproduces identically on a clean origin/main checkout: the flake8
hook's unpinned flake8-isort floated to isort 9.0.1 while the standalone isort
hook stayed rev-pinned to 6.0.1, and the two disagree about repeated
`from X import (...)` statements.

Cherry-picking the pin here so this PR can reach green without waiting on
#2281 to merge. It no-ops once main carries the same change.
The linter job on this PR fails with 10 I001/I005 findings in
opencontractserver/llms/agents/pydantic_ai_agents.py and
opencontractserver/utils/compact_pawls.py — files this PR does not touch. The
failure reproduces identically on a clean origin/main checkout: the flake8
hook's unpinned flake8-isort floated to isort 9.0.1 while the standalone isort
hook stayed rev-pinned to 6.0.1, and the two disagree about repeated
`from X import (...)` statements.

Only the flake8 pin is ported. #2281 also bumps this hook file's mypy stub
pins, but that half needs the type fixes that ship with it, so it stays there.

Cherry-picking so this PR can reach green without waiting on #2281 to merge.
It no-ops once main carries the same change.
@claude

claude Bot commented Aug 30, 2026

Copy link
Copy Markdown

Code Review

Reviewed the diff (.pre-commit-config.yaml + requirements/local.txt). Overall this is a good, well-documented fix for the flake8/isort pin-drift issue — the comment explaining the isort 6.0.1 vs 9.x disagreement is genuinely useful for future maintainers.

Bug: django-stubs version now mismatched between mypy hook and dev requirements

requirements/local.txt:10 bumps django-stubs from 6.0.7 → 6.1.0, but the mypy pre-commit hook's additional_dependencies (.pre-commit-config.yaml:102) still pins django-stubs==6.0.6.

This is exactly the failure mode the comment directly above that pin already warns about:

# additional_dependencies are resolved fresh every time the hook env is
# (re)built, so anything less than `==` can drift. Direct dependencies
# whose API surface mypy actually checks against are `==`-pinned and
# MUST match requirements/base.txt + requirements/local.txt.

With this PR merged, requirements/local.txt and the mypy hook's pinned django-stubs disagree (6.1.0 vs 6.0.6), so pre-commit run mypy type-checks against a different stub version than a contributor's local mypy run (installed from requirements/local.txt) or a non-pre-commit CI mypy invocation. That's the same class of CI-vs-local skew this PR is otherwise fixing for isort — worth bumping .pre-commit-config.yaml:102 to django-stubs==6.1.0 (or reverting the local.txt bump if it wasn't intentional) to keep the two in sync.

Other notes

  • The new flake8-isort==7.0.0 / isort==6.0.1 pins and rationale look correct and match the standalone isort hook's rev — good catch on the root cause.
  • No test coverage changes needed here since this is tooling/config only, though it might be worth a quick manual pre-commit run --all-files after fixing the django-stubs mismatch to confirm both hooks agree.

backend.yml's linter job runs mypy TWICE: the pinned pre-commit hook, and then
a second authoritative `python -m mypy --config-file mypy.ini` (backend.yml:107)
against whatever requirements/local.txt installs. So bumping django-stubs there
does gate CI, and 6.1.0 surfaces 7 errors this PR would otherwise land red with:

  QuerySets.py x6 - six guardian-permission id lists are a lazy `values_list`
  queryset in a `try` and `[]` in the matching `except LookupError`. 6.1.0 types
  `values_list(..., flat=True)` as `QuerySet[Model, int]`, which no longer
  unifies with `list[Never]`. Each now carries an explicit `Iterable[Any]`
  declaration — they are only ever consumed by an `__in` lookup.

  test_corpus_canonical_caml_migration.py x1 - the test asserts the model is
  GONE, so the lazy reference is unresolvable on purpose; 6.1.0's plugin
  resolves literal get_model() string pairs statically and errors on a miss.
  The name moves into a str-annotated local so there is no literal to match.
  Whether the error fires varies by interpreter and mypy version, which is why
  a `# type: ignore` is not used here.

Typing-only; no runtime behavior changes. No-ops once main carries #2281.
@claude

claude Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review

This is a dependabot bump of django-stubs 6.0.7 → 6.1.0, extended with three follow-on commits that fix the CI fallout (a pre-existing flake8-isort/isort drift unrelated to this bump, plus the actual type errors 6.1.0 introduces). Overall the changes are well-scoped, well-explained in the commit messages/comments, and don't touch runtime behavior.

Code quality

  • opencontractserver/shared/QuerySets.py: the Iterable[Any] annotations on permitted_ids/group_permitted_ids/doc_permitted_ids/etc. are the minimal, honest fix for the try/except type-widening mypy now catches (lazy values_list queryset vs. []). No behavior change — both are only ever consumed by __in.
  • opencontractserver/tests/test_corpus_canonical_caml_migration.py: swapping the literal "CorpusDescriptionRevision" for a str-annotated local to dodge django-stubs' static get_model() resolution is a reasonable way to keep the "model is gone" assertion intact without an unreliable # type: ignore (the comment correctly notes warn_unused_ignores makes that fragile across interpreter versions).
  • The .pre-commit-config.yaml flake8-isort/isort pin is well-justified and matches the isort hook's rev: 6.0.1 above it.

Possible gap

.pre-commit-config.yaml's mirrors-mypy hook still pins django-stubs==6.0.6 in additional_dependencies (line 102) — untouched by this PR. That comment block explicitly states these pins "MUST match requirements/base.txt + requirements/local.txt", but requirements/local.txt now points at 6.1.0 while the hook stays on 6.0.6 (already 6.0.6 vs. 6.0.7 pre-PR, so not new, but this PR widens the gap while directly touching this file for the adjacent flake8 pin and clearly being aware of the "hook deps drift silently" failure mode it documents on that same hook a few lines up).

Practical effect: CI's authoritative python -m mypy run (backend.yml:114, using requirements/local.txt) is what actually needs the QuerySets.py/test fixes in this PR — the pre-commit run --all-files step's mypy hook (using the stale 6.0.6 stub) never would have caught these in the first place. So CI stays green either way, but a contributor running pre-commit run --all-files locally is now checking against a stub version two minor releases behind what CI enforces, which is exactly the drift the file's own comments warn about. Worth bumping the hook's django-stubs pin to 6.1.0 in the same PR (or a fast follow) to keep the two in sync.

Tests / other

  • No new tests needed — this is a type-stub bump with no runtime behavior change, and the existing test suite (plus the adjusted migration test) covers it.
  • No changelog fragment added; given this is a dev-dependency/typing-only change I don't think one is required under the "when to add a fragment" criteria in CLAUDE.md, but flagging in case the team's convention differs for dependency PRs.

Nice, well-documented root-causing in the commit messages (especially isolating the flake8-isort/isort disagreement and the interpreter-version-dependent # type: ignore issue) — good faith effort to get a routine dependency bump to green without papering over the underlying causes.

JSv4 commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

Picked this up as part of a batch pass over the open PRs. The review above ended with:

per the changelog this release includes "Support custom arguments in queryset update methods" and "Explicit through default manager" — these change how mypy type-checks certain Django ORM patterns … Worth running mypy (or the pre-commit hook that wraps it) locally to confirm no new type errors surface.

Ran it. New type errors do surface — 7 of them, and they land exactly where that review predicted: on guardian's *UserObjectPermission / *GroupObjectPermission through-models.

Why CI would have caught this (and why it's easy to assume otherwise)

backend.yml's linter job runs mypy twice: once via the pre-commit hook — which pins its own stubs in additional_dependencies and so is unaffected by this file — and again at backend.yml:107:

python -m mypy --config-file mypy.ini opencontractserver config

That second run uses whatever requirements/local.txt installs, which is what this PR changes. That is the invocation that goes red.

The 7 errors

Six in opencontractserver/shared/QuerySets.py (lines 473/491/660/661/675/676), all the same shape — a permission-id list built as a lazy values_list queryset inside a try and falling back to [] in the matching except LookupError:

error: Incompatible types in assignment (expression has type "list[Never]",
variable has type "QuerySet[DocumentUserObjectPermission, int]")  [assignment]

6.1.0 types values_list(..., flat=True) precisely enough that the two arms no longer unify. Each variable now carries an explicit Iterable[Any] declaration — every one of them is only ever consumed by an __in lookup, so that is the accurate common type.

One in opencontractserver/tests/test_corpus_canonical_caml_migration.py — the test asserts apps.get_model("corpuses", "CorpusDescriptionRevision") raises LookupError, i.e. the lazy reference is unresolvable on purpose, but 6.1.0's plugin resolves literal get_model() string pairs statically and errors on a miss. The name moved into a str-annotated local so there is no literal to match. (A # type: ignore was the first attempt and is not reliable here — it fires under mypy 2.3.0 but not under the hook's 2.0.0, and mypy.ini sets warn_unused_ignores, so the comment cannot be correct in both.)

All typing-only; no runtime behavior changes. Fixes ported from #2281.

Verified with CI's exact command and this branch's exact pins (mypy 2.3.0 + django-stubs 6.1.0): Success: no issues found in 1559 source files — against Found 7 errors in 2 files with the fixes reverted.

Also on this branch

linter was separately red with 10 I001/I005 findings in two files this PR doesn't touch, reproducing identically on a clean main — the flake8 hook's unpinned flake8-isort had floated to isort 9.0.1 while the isort hook stayed pinned to 6.0.1. Pin ported from #2281; no-ops once that merges.

Note for whoever merges

#2260 also needs django-stubs>=6.0.9 (djangorestframework-stubs 3.18.0 requires it), so it now carries the same 6.1.0 pin. The two PRs agree rather than conflict, and whichever lands second is a no-op on that line.


Generated by Claude Code

@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@JSv4
JSv4 merged commit 1fe97d4 into main Aug 30, 2026
16 checks passed
@dependabot
dependabot Bot deleted the dependabot/pip/django-stubs-6.1.0 branch August 30, 2026 11:34
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

dependencies Pull requests that update a dependency file python Pull requests that update Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants