From 5427b269708c13654bc50405c80947db637d8d60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 12:33:01 +0000 Subject: [PATCH 1/4] Bump django-stubs from 6.0.6 to 6.0.7 Bumps [django-stubs](https://github.com/typeddjango/django-stubs) from 6.0.6 to 6.0.7. - [Release notes](https://github.com/typeddjango/django-stubs/releases) - [Commits](https://github.com/typeddjango/django-stubs/compare/6.0.6...6.0.7) --- updated-dependencies: - dependency-name: django-stubs dependency-version: 6.0.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/local.txt b/requirements/local.txt index b1ee9f497..055644674 100644 --- a/requirements/local.txt +++ b/requirements/local.txt @@ -7,7 +7,7 @@ watchfiles==1.2.0 # https://github.com/samuelcolvin/watchfiles # ------------------------------------------------------------------------------ mypy==2.3.0 # https://github.com/python/mypy -django-stubs==6.0.6 # https://github.com/typeddjango/django-stubs +django-stubs==6.0.7 # https://github.com/typeddjango/django-stubs pytest==9.1.1 # https://github.com/pytest-dev/pytest pytest-cov==7.1.0 # https://github.com/pytest-dev/pytest-cov pytest-xdist==3.8.0 # https://github.com/pytest-dev/pytest-xdist (parallel test execution) From f0f06e57f3b31c2c5a6ce43950188dab442d7c26 Mon Sep 17 00:00:00 2001 From: JSv4 Date: Sat, 25 Jul 2026 10:44:36 -0500 Subject: [PATCH 2/4] Fix typing errors with django-stubs 6.0.7 --- opencontractserver/documents/services/relationships.py | 4 ++-- opencontractserver/shared/fields.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/opencontractserver/documents/services/relationships.py b/opencontractserver/documents/services/relationships.py index 5031397c0..0afffb758 100644 --- a/opencontractserver/documents/services/relationships.py +++ b/opencontractserver/documents/services/relationships.py @@ -112,12 +112,12 @@ def get_relationship_counts_by_document( # relationship where source == target only contributes once. Without # this guard, such a row would be counted both as a source and as a # target for the same document. - for row in ( + for target_row in ( qs.exclude(source_document_id=F("target_document_id")) .values("target_document_id") .annotate(c=Count("id")) ): - counts[row["target_document_id"]] += row["c"] + counts[target_row["target_document_id"]] += target_row["c"] # Materialise to a plain dict so callers can ``.get(key, 0)`` without # accidentally mutating the defaultdict. diff --git a/opencontractserver/shared/fields.py b/opencontractserver/shared/fields.py index 67486aa23..2a4a592c3 100644 --- a/opencontractserver/shared/fields.py +++ b/opencontractserver/shared/fields.py @@ -70,5 +70,5 @@ class NullableJSONField(DbJSONField): empty_values = [None, "", [], (), {}] - def formfield(self, **kwargs: Any) -> Any: # type: ignore[override] + def formfield(self, **kwargs: Any) -> Any: return super().formfield(**{"form_class": UTF8JSONFormField, **kwargs}) From cd2aa296a2281d94c782e5aa25c3317a4def4c52 Mon Sep 17 00:00:00 2001 From: JSv4 Date: Sat, 25 Jul 2026 10:52:46 -0500 Subject: [PATCH 3/4] Support django field signatures across stub versions --- opencontractserver/shared/fields.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/opencontractserver/shared/fields.py b/opencontractserver/shared/fields.py index 2a4a592c3..28b5c40c5 100644 --- a/opencontractserver/shared/fields.py +++ b/opencontractserver/shared/fields.py @@ -70,5 +70,15 @@ class NullableJSONField(DbJSONField): empty_values = [None, "", [], (), {}] - def formfield(self, **kwargs: Any) -> Any: - return super().formfield(**{"form_class": UTF8JSONFormField, **kwargs}) + def formfield( + self, + form_class: Optional[type[Any]] = None, + choices_form_class: Optional[type[Any]] = None, + **kwargs: Any, + ) -> Any: + formfield_kwargs = {"form_class": UTF8JSONFormField, **kwargs} + if form_class is not None: + formfield_kwargs["form_class"] = form_class + if choices_form_class is not None: + formfield_kwargs["choices_form_class"] = choices_form_class + return super().formfield(**formfield_kwargs) From 7d714670e0bff5567ac6d5253a6d72dac54f954b Mon Sep 17 00:00:00 2001 From: JSv4 Date: Sat, 25 Jul 2026 14:42:38 -0500 Subject: [PATCH 4/4] Fix Codecov coverage for django stubs update --- .../documents/services/relationships.py | 8 ++++---- opencontractserver/shared/fields.py | 13 ++++++------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/opencontractserver/documents/services/relationships.py b/opencontractserver/documents/services/relationships.py index 0afffb758..9636ec35a 100644 --- a/opencontractserver/documents/services/relationships.py +++ b/opencontractserver/documents/services/relationships.py @@ -106,18 +106,18 @@ def get_relationship_counts_by_document( qs = qs.filter(corpus_id=corpus_id) counts: defaultdict[int, int] = defaultdict(int) - for row in qs.values("source_document_id").annotate(c=Count("id")): - counts[row["source_document_id"]] += row["c"] + for source_row in qs.values("source_document_id").annotate(c=Count("id")): + counts[source_row["source_document_id"]] += source_row["c"] # Exclude self-referential rows from the target-side aggregation so a # relationship where source == target only contributes once. Without # this guard, such a row would be counted both as a source and as a # target for the same document. - for target_row in ( + for row in ( qs.exclude(source_document_id=F("target_document_id")) .values("target_document_id") .annotate(c=Count("id")) ): - counts[target_row["target_document_id"]] += target_row["c"] + counts[row["target_document_id"]] += row["c"] # Materialise to a plain dict so callers can ``.get(key, 0)`` without # accidentally mutating the defaultdict. diff --git a/opencontractserver/shared/fields.py b/opencontractserver/shared/fields.py index 28b5c40c5..95104d23e 100644 --- a/opencontractserver/shared/fields.py +++ b/opencontractserver/shared/fields.py @@ -72,13 +72,12 @@ class NullableJSONField(DbJSONField): def formfield( self, - form_class: Optional[type[Any]] = None, + form_class: Optional[type[Any]] = UTF8JSONFormField, choices_form_class: Optional[type[Any]] = None, **kwargs: Any, ) -> Any: - formfield_kwargs = {"form_class": UTF8JSONFormField, **kwargs} - if form_class is not None: - formfield_kwargs["form_class"] = form_class - if choices_form_class is not None: - formfield_kwargs["choices_form_class"] = choices_form_class - return super().formfield(**formfield_kwargs) + return super().formfield( + form_class=form_class, + choices_form_class=choices_form_class, + **kwargs, + )