From f566734799afd7bbcd20290958fc1424b067a262 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Mon, 31 Oct 2022 12:11:07 +0000 Subject: [PATCH] Re-allow expressions in UniqueConstraint (#1220) --- django-stubs/db/models/constraints.pyi | 23 ++++++++---- .../typecheck/db/models/test_constraints.yml | 37 +++++++++++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 tests/typecheck/db/models/test_constraints.yml diff --git a/django-stubs/db/models/constraints.pyi b/django-stubs/db/models/constraints.pyi index a14f2f5..29df968 100644 --- a/django-stubs/db/models/constraints.pyi +++ b/django-stubs/db/models/constraints.pyi @@ -1,5 +1,5 @@ from enum import Enum -from typing import Any, Optional, Sequence, Tuple, Type, TypeVar, Union +from typing import Any, Optional, Sequence, Tuple, Type, TypeVar, Union, overload from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.models.base import Model @@ -32,14 +32,23 @@ class UniqueConstraint(BaseConstraint): fields: Tuple[str, ...] condition: Optional[Q] deferrable: Optional[Deferrable] + + @overload def __init__( self, - *, - # For 4.0: - # *expressions: Union[str, Combinable], - # fields: Optional[Sequence[str]] = ..., - # name: str = ..., - fields: Optional[Sequence[str]], + *expressions: Union[str, Combinable], + fields: None = ..., + name: str, + condition: Optional[Q] = ..., + deferrable: Optional[Deferrable] = ..., + include: Optional[Sequence[str]] = ..., + opclasses: Sequence[Any] = ..., + ) -> None: ... + @overload + def __init__( + self, + *, + fields: Sequence[str], name: str, condition: Optional[Q] = ..., deferrable: Optional[Deferrable] = ..., diff --git a/tests/typecheck/db/models/test_constraints.yml b/tests/typecheck/db/models/test_constraints.yml new file mode 100644 index 0000000..72bf38a --- /dev/null +++ b/tests/typecheck/db/models/test_constraints.yml @@ -0,0 +1,37 @@ +- case: unique_constraint_expressions + main: | + from django.db.models import Q, UniqueConstraint + from django.db.models.functions import Lower + + UniqueConstraint( + Lower('name').desc(), + 'category', + name='unique_lower_name_category', + ) + +- case: unique_constraint_fields + main: | + from django.db.models import Q, UniqueConstraint + from django.db.models.functions import Lower + + UniqueConstraint( + fields=['name'], + name='unqiue_name', + ) + +- case: unique_constraint_expressions_fields + main: | + from django.db.models import Q, UniqueConstraint + from django.db.models.functions import Lower + + UniqueConstraint( + Lower('name'), + fields=['name'], + name='unique_mess', + ) + regex: true + out: | + main:4: error: No overload variant of "UniqueConstraint" matches argument types "Lower", "List\[str\]", "str" + main:4: note: Possible overload variants: + main:4: note: .* + main:4: note: .*