enable more test folders: db.functions

This commit is contained in:
Maxim Kurnikov
2019-01-30 16:53:22 +03:00
parent 1868100bd9
commit 8a952b416e
10 changed files with 117 additions and 34 deletions

View File

@@ -1,13 +1,14 @@
from collections import OrderedDict from collections import OrderedDict
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Any, Callable, Dict, Iterator, List, Optional, Set, Tuple, Type, Union, Sequence from typing import Any, Callable, Dict, Iterator, List, Optional, Sequence, Set, Tuple, Type, Union
from django.db.models import QuerySet, Q
from django.db.models.fields import Field
from django.db.models.lookups import Lookup from django.db.models.lookups import Lookup
from django.db.models.sql import Query
from django.db.models.sql.compiler import SQLCompiler from django.db.models.sql.compiler import SQLCompiler
from django.db.models import Q, QuerySet
from django.db.models.fields import Field
from django.db.models.sql import Query
_OutputField = Union[Field, str] _OutputField = Union[Field, str]
class SQLiteNumericMixin: class SQLiteNumericMixin:
@@ -55,7 +56,6 @@ class BaseExpression:
def get_db_converters(self, connection: Any) -> List[Callable]: ... def get_db_converters(self, connection: Any) -> List[Callable]: ...
def get_source_expressions(self) -> List[Any]: ... def get_source_expressions(self) -> List[Any]: ...
def set_source_expressions(self, exprs: List[Any]) -> None: ... def set_source_expressions(self, exprs: List[Any]) -> None: ...
def as_sql(self, compiler: Any, connection: Any, **kwargs) -> None: ...
def contains_aggregate(self) -> bool: ... def contains_aggregate(self) -> bool: ...
def contains_over_clause(self) -> bool: ... def contains_over_clause(self) -> bool: ...
def contains_column_references(self) -> bool: ... def contains_column_references(self) -> bool: ...
@@ -83,6 +83,12 @@ class BaseExpression:
def reverse_ordering(self): ... def reverse_ordering(self): ...
def flatten(self) -> Iterator[Expression]: ... def flatten(self) -> Iterator[Expression]: ...
def __hash__(self) -> int: ... def __hash__(self) -> int: ...
def deconstruct(self) -> Any: ...
def as_sqlite(self, compiler: SQLCompiler, connection: Any) -> Any: ...
def as_sql(self, compiler: SQLCompiler, connection: Any, **extra_context: Any) -> Any: ...
def as_mysql(self, compiler: Any, connection: Any) -> Any: ...
def as_postgresql(self, compiler: Any, connection: Any) -> Any: ...
def as_oracle(self, compiler: Any, connection: Any): ...
class Expression(BaseExpression, Combinable): ... class Expression(BaseExpression, Combinable): ...
@@ -117,6 +123,7 @@ class F(Combinable):
) -> Expression: ... ) -> Expression: ...
def asc(self, **kwargs) -> OrderBy: ... def asc(self, **kwargs) -> OrderBy: ...
def desc(self, **kwargs) -> OrderBy: ... def desc(self, **kwargs) -> OrderBy: ...
def deconstruct(self) -> Any: ...
class OuterRef(F): ... class OuterRef(F): ...

View File

@@ -18,3 +18,44 @@ from .text import (
Replace as Replace, Replace as Replace,
Substr as Substr, Substr as Substr,
) )
from .window import (
CumeDist as CumeDist,
DenseRank as DenseRank,
FirstValue as FirstValue,
Lag as Lag,
LastValue as LastValue,
Lead as Lead,
NthValue as NthValue,
Ntile as Ntile,
PercentRank as PercentRank,
Rank as Rank,
RowNumber as RowNumber,
)
from .datetime import (
Extract as Extract,
ExtractDay as ExtractDay,
ExtractHour as ExtractHour,
ExtractMinute as ExtractMinute,
ExtractSecond as ExtractSecond,
ExtractMonth as ExtractMonth,
ExtractQuarter as ExtractQuarter,
ExtractWeek as ExtractWeek,
ExtractWeekDay as ExtractWeekDay,
ExtractYear as ExtractYear,
Trunc as Trunc,
TruncDate as TruncDate,
TruncDay as TruncDay,
TruncHour as TruncHour,
TruncMinute as TruncMinute,
TruncQuarter as TruncQuarter,
TruncMonth as TruncMonth,
TruncSecond as TruncSecond,
TruncTime as TruncTime,
TruncWeek as TruncWeek,
TruncYear as TruncYear,
Now as Now,
)
from .comparison import Coalesce as Coalesce, Greatest as Greatest, Least as Least, Cast as Cast

View File

@@ -1,12 +1,11 @@
from datetime import date, datetime from datetime import date
from decimal import Decimal from decimal import Decimal
from typing import Any, List, Optional, Tuple, Union from typing import Any, Callable, Dict, List, Union
from django.db.models.expressions import Combinable, Expression
from django.db.backends.sqlite3.base import DatabaseWrapper
from django.db.models import Func from django.db.models import Func
from django.db.models.expressions import Value
from django.db.models.fields import Field from django.db.models.fields import Field
from django.db.models.sql.compiler import SQLCompiler
class Cast(Func): class Cast(Func):
contains_aggregate: bool contains_aggregate: bool
@@ -14,15 +13,10 @@ class Cast(Func):
extra: Dict[Any, Any] extra: Dict[Any, Any]
is_summary: bool is_summary: bool
output_field: Field output_field: Field
source_expressions: List[django.db.models.expressions.Combinable] source_expressions: List[Combinable]
function: str = ... function: str = ...
template: str = ... template: str = ...
def __init__(self, expression: Union[date, Decimal, Value, str], output_field: Field) -> None: ... def __init__(self, expression: Union[date, Decimal, Expression, str], output_field: Union[str, Field]) -> None: ...
def as_sql(
self, compiler: SQLCompiler, connection: DatabaseWrapper, **extra_context: Any
) -> Tuple[str, Union[List[date], List[Decimal]]]: ...
def as_mysql(self, compiler: Any, connection: Any): ...
def as_postgresql(self, compiler: Any, connection: Any): ...
class Coalesce(Func): class Coalesce(Func):
contains_aggregate: bool contains_aggregate: bool
@@ -30,10 +24,9 @@ class Coalesce(Func):
extra: Dict[Any, Any] extra: Dict[Any, Any]
is_summary: bool is_summary: bool
output_field: Field output_field: Field
source_expressions: List[django.db.models.expressions.Combinable] source_expressions: List[Combinable]
function: str = ... function: str = ...
def __init__(self, *expressions: Any, **extra: Any) -> None: ... def __init__(self, *expressions: Any, **extra: Any) -> None: ...
def as_oracle(self, compiler: Any, connection: Any): ...
class Greatest(Func): class Greatest(Func):
contains_aggregate: bool contains_aggregate: bool
@@ -42,10 +35,9 @@ class Greatest(Func):
extra: Dict[Any, Any] extra: Dict[Any, Any]
is_summary: bool is_summary: bool
output_field: Field output_field: Field
source_expressions: List[django.db.models.expressions.Combinable] source_expressions: List[Combinable]
function: str = ... function: str = ...
def __init__(self, *expressions: Any, **extra: Any) -> None: ... def __init__(self, *expressions: Any, **extra: Any) -> None: ...
def as_sqlite(self, compiler: SQLCompiler, connection: DatabaseWrapper) -> Tuple[str, List[datetime]]: ...
class Least(Func): class Least(Func):
contains_aggregate: bool contains_aggregate: bool
@@ -54,7 +46,6 @@ class Least(Func):
extra: Dict[Any, Any] extra: Dict[Any, Any]
is_summary: bool is_summary: bool
output_field: Field output_field: Field
source_expressions: List[django.db.models.expressions.Combinable] source_expressions: List[Combinable]
function: str = ... function: str = ...
def __init__(self, *expressions: Any, **extra: Any) -> None: ... def __init__(self, *expressions: Any, **extra: Any) -> None: ...
def as_sqlite(self, compiler: SQLCompiler, connection: DatabaseWrapper) -> Tuple[str, List[datetime]]: ...

View File

@@ -6,6 +6,8 @@ from django.db import models
from django.db.models import Manager from django.db.models import Manager
from django.db.models.sql.query import Query, RawQuery from django.db.models.sql.query import Query, RawQuery
from django.db.models.expressions import F, Combinable
_T = TypeVar("_T", bound=models.Model, covariant=True) _T = TypeVar("_T", bound=models.Model, covariant=True)
class QuerySet(Iterable[_T], Sized): class QuerySet(Iterable[_T], Sized):
@@ -35,14 +37,14 @@ class QuerySet(Iterable[_T], Sized):
def aggregate(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: ... def aggregate(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: ...
def get(self, *args: Any, **kwargs: Any) -> _T: ... def get(self, *args: Any, **kwargs: Any) -> _T: ...
def create(self, **kwargs: Any) -> _T: ... def create(self, **kwargs: Any) -> _T: ...
def bulk_create(self, objs: Sequence[Model], batch_size: Optional[int] = ...) -> List[_T]: ... def bulk_create(self, objs: Iterable[Model], batch_size: Optional[int] = ...) -> List[_T]: ...
def get_or_create(self, defaults: Optional[Dict[str, Any]] = ..., **kwargs: Any) -> Tuple[_T, bool]: ... def get_or_create(self, defaults: Optional[Dict[str, Any]] = ..., **kwargs: Any) -> Tuple[_T, bool]: ...
def update_or_create(self, defaults: Optional[Dict[str, Any]] = ..., **kwargs: Any) -> Tuple[_T, bool]: ... def update_or_create(self, defaults: Optional[Dict[str, Any]] = ..., **kwargs: Any) -> Tuple[_T, bool]: ...
def earliest(self, *fields: Any, field_name: Optional[Any] = ...) -> _T: ... def earliest(self, *fields: Any, field_name: Optional[Any] = ...) -> _T: ...
def latest(self, *fields: Any, field_name: Optional[Any] = ...) -> _T: ... def latest(self, *fields: Any, field_name: Optional[Any] = ...) -> _T: ...
def first(self) -> Optional[_T]: ... def first(self) -> Optional[_T]: ...
def last(self) -> Optional[_T]: ... def last(self) -> Optional[_T]: ...
def in_bulk(self, id_list: Any = ..., *, field_name: str = ...) -> Dict[str, models.Model]: ... def in_bulk(self, id_list: Any = ..., *, field_name: str = ...) -> Dict[Union[int, str], models.Model]: ...
def delete(self) -> Tuple[int, Dict[str, int]]: ... def delete(self) -> Tuple[int, Dict[str, int]]: ...
def update(self, **kwargs: Any) -> int: ... def update(self, **kwargs: Any) -> int: ...
def _update(self, values: Any) -> Optional[Any]: ... def _update(self, values: Any) -> Optional[Any]: ...
@@ -51,8 +53,8 @@ class QuerySet(Iterable[_T], Sized):
def raw( def raw(
self, raw_query: str, params: Any = ..., translations: Optional[Dict[str, str]] = ..., using: None = ... self, raw_query: str, params: Any = ..., translations: Optional[Dict[str, str]] = ..., using: None = ...
) -> RawQuerySet: ... ) -> RawQuerySet: ...
def values(self, *fields: str, **expressions: Any) -> QuerySet: ... def values(self, *fields: Union[str, Combinable], **expressions: Any) -> QuerySet: ...
def values_list(self, *fields: str, flat: bool = ..., named: bool = ...) -> QuerySet: ... def values_list(self, *fields: Union[str, Combinable], flat: bool = ..., named: bool = ...) -> QuerySet: ...
def dates(self, field_name: str, kind: str, order: str = ...) -> QuerySet: ... def dates(self, field_name: str, kind: str, order: str = ...) -> QuerySet: ...
def datetimes(self, field_name: str, kind: str, order: str = ..., tzinfo: None = ...) -> QuerySet: ... def datetimes(self, field_name: str, kind: str, order: str = ..., tzinfo: None = ...) -> QuerySet: ...
def none(self) -> QuerySet[_T]: ... def none(self) -> QuerySet[_T]: ...

View File

@@ -50,6 +50,7 @@ class DeferredAttribute:
def __get__(self, instance: Optional[Model], cls: Type[Model] = ...) -> Any: ... def __get__(self, instance: Optional[Model], cls: Type[Model] = ...) -> Any: ...
class RegisterLookupMixin: class RegisterLookupMixin:
lookup_name: str
@classmethod @classmethod
def get_lookups(cls) -> Dict[str, Any]: ... def get_lookups(cls) -> Dict[str, Any]: ...
def get_lookup(self, lookup_name: str) -> Optional[Any]: ... def get_lookup(self, lookup_name: str) -> Optional[Any]: ...

View File

@@ -1 +1 @@
from ..query import Query as Query, RawQuery as RawQuery from .query import Query as Query, RawQuery as RawQuery

View File

@@ -6,7 +6,8 @@ from uuid import UUID
from django.db.models.base import Model from django.db.models.base import Model
from django.db.models.expressions import BaseExpression, Expression from django.db.models.expressions import BaseExpression, Expression
from django.db.models.sql import Query, RawQuery
from django.db.models.sql.query import Query, RawQuery
FORCE: Any FORCE: Any

View File

@@ -0,0 +1,14 @@
from typing import Dict, Pattern, Tuple
GET_ITERATOR_CHUNK_SIZE: int = ...
MULTI: str = ...
SINGLE: str = ...
CURSOR: str = ...
NO_RESULTS: str = ...
ORDER_PATTERN: Pattern = ...
ORDER_DIR: Dict[str, Tuple[str, str]] = ...
INNER: str = ...
LOUTER: str = ...

View File

@@ -13,6 +13,7 @@ from .utils import (
modify_settings as modify_settings, modify_settings as modify_settings,
override_script_prefix as override_script_prefix, override_script_prefix as override_script_prefix,
override_system_checks as override_system_checks, override_system_checks as override_system_checks,
ignore_warnings as ignore_warnings,
) )
from .client import Client as Client, RequestFactory as RequestFactory from .client import Client as Client, RequestFactory as RequestFactory

View File

@@ -42,6 +42,8 @@ IGNORED_ERROR_PATTERNS = [
'"NullTranslations" has no attribute "_catalog"', '"NullTranslations" has no attribute "_catalog"',
'Definition of "as_sql" in base class', 'Definition of "as_sql" in base class',
'expression has type "property"', 'expression has type "property"',
'"object" has no attribute "__iter__"',
'Too few arguments for "dates" of "QuerySet"',
re.compile(r'"Callable\[\[(Any(, )?)+\], Any\]" has no attribute'), re.compile(r'"Callable\[\[(Any(, )?)+\], Any\]" has no attribute'),
re.compile(r'"HttpResponseBase" has no attribute "[A-Za-z_]+"'), re.compile(r'"HttpResponseBase" has no attribute "[A-Za-z_]+"'),
re.compile(r'Incompatible types in assignment \(expression has type "Tuple\[\]", ' re.compile(r'Incompatible types in assignment \(expression has type "Tuple\[\]", '
@@ -52,7 +54,7 @@ IGNORED_ERROR_PATTERNS = [
# TODO: remove when reassignment will be possible (in 0.670? ) # TODO: remove when reassignment will be possible (in 0.670? )
re.compile(r'Incompatible types in assignment \(expression has type "(QuerySet|List){1}\[[A-Za-z, ]+\]", ' re.compile(r'Incompatible types in assignment \(expression has type "(QuerySet|List){1}\[[A-Za-z, ]+\]", '
r'variable has type "(QuerySet|List){1}\[[A-Za-z, ]+\]"\)'), r'variable has type "(QuerySet|List){1}\[[A-Za-z, ]+\]"\)'),
re.compile(r'"MockRequest" has no attribute "[a-zA-Z_]+"'), re.compile(r'"(MockRequest|DummyRequest|DummyUser)" has no attribute "[a-zA-Z_]+"'),
] ]
# Test folders to typecheck # Test folders to typecheck
@@ -64,20 +66,20 @@ TESTS_DIRS = [
'admin_custom_urls', 'admin_custom_urls',
'admin_default_site', 'admin_default_site',
'admin_docs', 'admin_docs',
# # TODO: 'admin_filters', # TODO: 'admin_filters',
'admin_inlines', 'admin_inlines',
'admin_ordering', 'admin_ordering',
'admin_registration', 'admin_registration',
'admin_scripts', 'admin_scripts',
# # TODO: 'admin_utils', # TODO: 'admin_utils',
# # TODO: 'admin_views', # TODO: 'admin_views',
'admin_widgets', 'admin_widgets',
'aggregation', 'aggregation',
'aggregation_regress', 'aggregation_regress',
'annotations', 'annotations',
'app_loading', 'app_loading',
'apps', 'apps',
# # TODO: auth_tests # TODO: auth_tests
'base', 'base',
'bash_completion', 'bash_completion',
'basic', 'basic',
@@ -92,6 +94,29 @@ TESTS_DIRS = [
'csrf_tests', 'csrf_tests',
'custom_columns', 'custom_columns',
# TODO: 'custom_lookups', # TODO: 'custom_lookups',
# TODO: 'custom_managers',
'custom_methods',
'custom_migration_operations',
'custom_pk',
'datatypes',
'dates',
'datetimes',
'db_functions',
'db_typecasts',
'db_utils',
'dbshell',
# TODO: 'decorators',
'defer',
# TODO: 'defer_regress',
'delete',
'delete_regress',
# TODO: 'deprecation',
# TODO: 'dispatch',
'distinct_on_fields',
'empty',
# TODO: 'expressions',
'expressions_case',
# TODO: 'expressions_window'
] ]