Skip to content

Commit 42ddece

Browse files
Lookup should be a subtype of Expression (#2199)
* Lookup should be a subtype of Expression * [pre-commit.ci] auto fixes from pre-commit.com hooks --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 042e394 commit 42ddece

File tree

5 files changed

+17
-19
lines changed

5 files changed

+17
-19
lines changed

django-stubs/db/models/expressions.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class BaseExpression:
6565
def __init__(self, output_field: Field | None = ...) -> None: ...
6666
def get_db_converters(self, connection: BaseDatabaseWrapper) -> list[Callable]: ...
6767
def get_source_expressions(self) -> list[Any]: ...
68-
def set_source_expressions(self, exprs: Sequence[Combinable]) -> None: ...
68+
def set_source_expressions(self, exprs: Sequence[Combinable | Expression]) -> None: ...
6969
@cached_property
7070
def contains_aggregate(self) -> bool: ...
7171
@cached_property
@@ -92,7 +92,7 @@ class BaseExpression:
9292
def convert_value(self) -> Callable: ...
9393
def get_lookup(self, lookup: str) -> type[Lookup] | None: ...
9494
def get_transform(self, name: str) -> type[Transform] | None: ...
95-
def relabeled_clone(self, change_map: dict[str | None, str]) -> Self: ...
95+
def relabeled_clone(self, change_map: Mapping[str, str]) -> Self: ...
9696
def copy(self) -> Self: ...
9797
def get_group_by_cols(self) -> list[BaseExpression]: ...
9898
def get_source_fields(self) -> list[Field | None]: ...

django-stubs/db/models/lookups.pyi

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
from collections.abc import Iterable, Mapping
2-
from typing import Any, Generic, Literal, TypeVar
1+
from collections.abc import Iterable
2+
from typing import Any, Generic, Literal, Sequence, TypeVar
33

44
from django.core.exceptions import EmptyResultSet
55
from django.db.backends.base.base import BaseDatabaseWrapper
6-
from django.db.models.expressions import Expression, Func
6+
from django.db.models.expressions import Combinable, Expression, Func
77
from django.db.models.fields import BooleanField
88
from django.db.models.query_utils import RegisterLookupMixin
99
from django.db.models.sql.compiler import SQLCompiler, _AsSqlType, _ParamT
1010
from django.utils.datastructures import OrderedSet
1111
from django.utils.functional import cached_property
12-
from typing_extensions import Self
1312

1413
_T = TypeVar("_T")
1514

16-
class Lookup(Generic[_T]):
15+
class Lookup(Expression, Generic[_T]):
1716
lookup_name: str
1817
prepare_rhs: bool
1918
can_use_none_as_rhs: bool
@@ -26,16 +25,14 @@ class Lookup(Generic[_T]):
2625
self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, rhs: OrderedSet | None = ...
2726
) -> tuple[list[str], list[str]]: ...
2827
def get_source_expressions(self) -> list[Expression]: ...
29-
def set_source_expressions(self, new_exprs: list[Expression]) -> None: ...
28+
def set_source_expressions(self, new_exprs: Sequence[Combinable | Expression]) -> None: ...
3029
def get_prep_lookup(self) -> Any: ...
3130
def get_db_prep_lookup(self, value: _ParamT, connection: BaseDatabaseWrapper) -> _AsSqlType: ...
3231
def process_lhs(
3332
self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, lhs: Expression | None = ...
3433
) -> _AsSqlType: ...
3534
def process_rhs(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> _AsSqlType: ...
3635
def rhs_is_direct_value(self) -> bool: ...
37-
def relabeled_clone(self, relabels: Mapping[str, str]) -> Self: ...
38-
def get_group_by_cols(self) -> list[Expression]: ...
3936
def as_sql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> _AsSqlType: ...
4037
def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> _AsSqlType: ...
4138
@cached_property
@@ -45,8 +42,6 @@ class Lookup(Generic[_T]):
4542
@cached_property
4643
def contains_over_clause(self) -> bool: ...
4744
@property
48-
def is_summary(self) -> bool: ...
49-
@property
5045
def identity(self) -> tuple[type[Lookup], Any, Any]: ...
5146

5247
class Transform(RegisterLookupMixin, Func):

django-stubs/db/models/sql/query.pyi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ class Query(BaseExpression):
9494
def get_meta(self) -> Options: ...
9595
def clone(self) -> Query: ...
9696
def chain(self, klass: type[Query] | None = ...) -> Query: ...
97-
def relabeled_clone(self, change_map: dict[str | None, str]) -> Query: ...
9897
def get_count(self, using: str) -> int: ...
9998
def has_filters(self) -> WhereNode: ...
10099
def has_results(self, using: str) -> bool: ...

scripts/stubtest/allowlist_todo.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,6 @@ django.contrib.gis.db.models.Lookup.get_prep_lhs
334334
django.contrib.gis.db.models.Lookup.allowed_default
335335
django.contrib.gis.db.models.Lookup.lookup_name
336336
django.contrib.gis.db.models.Lookup.output_field
337-
django.contrib.gis.db.models.Lookup.relabeled_clone
338-
django.contrib.gis.db.models.Lookup.resolve_expression
339337
django.contrib.gis.db.models.Lookup.select_format
340338
django.contrib.gis.db.models.Manager.__slotnames__
341339
django.contrib.gis.db.models.ManyToManyField.__get__
@@ -764,8 +762,6 @@ django.db.models.Lookup.get_prep_lhs
764762
django.db.models.Lookup.lookup_name
765763
django.db.models.Lookup.allowed_default
766764
django.db.models.Lookup.output_field
767-
django.db.models.Lookup.relabeled_clone
768-
django.db.models.Lookup.resolve_expression
769765
django.db.models.Lookup.select_format
770766
django.db.models.Manager.__slotnames__
771767
django.db.models.ManyToManyField.__get__
@@ -1080,8 +1076,6 @@ django.db.models.lookups.Lookup.get_prep_lhs
10801076
django.db.models.lookups.Lookup.allowed_default
10811077
django.db.models.lookups.Lookup.lookup_name
10821078
django.db.models.lookups.Lookup.output_field
1083-
django.db.models.lookups.Lookup.relabeled_clone
1084-
django.db.models.lookups.Lookup.resolve_expression
10851079
django.db.models.lookups.Lookup.select_format
10861080
django.db.models.lookups.PatternLookup.process_rhs
10871081
django.db.models.manager.BaseManager.aaggregate

tests/typecheck/db/models/test_constraints.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,13 @@
3535
main:4: note: Possible overload variants:
3636
main:4: note: .*
3737
main:4: note: .*
38+
39+
- case: model_level_check_contraint_should_allow_lookups
40+
main: |
41+
from django.db.models import CheckConstraint, F
42+
from django.db.models.lookups import LessThan
43+
44+
CheckConstraint(
45+
name="less_than_constraint",
46+
check=LessThan(F("months"), 1)
47+
)

0 commit comments

Comments
 (0)