mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-10 22:11:54 +08:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd057010f6 | ||
|
|
3d2534ea8d | ||
|
|
54f5f63e71 | ||
|
|
4c5723d368 | ||
|
|
7e0e43135d | ||
|
|
e05b84e32d | ||
|
|
71751d3795 | ||
|
|
25f92e8e56 | ||
|
|
28d47c7e93 | ||
|
|
197cb4058e | ||
|
|
dac2b31fb2 | ||
|
|
8d2600136a | ||
|
|
570772f973 | ||
|
|
d5c1bfb12a | ||
|
|
64cbb0f70e | ||
|
|
6f5a39625e | ||
|
|
bf604a0398 | ||
|
|
92c8dfc93f | ||
|
|
c10c55052c | ||
|
|
96914e466b | ||
|
|
90ed7f332d | ||
|
|
a801501151 | ||
|
|
8ea59985df | ||
|
|
2964ed53d7 | ||
|
|
1b9176f994 | ||
|
|
54d0d018c6 |
@@ -4,10 +4,19 @@ dist: xenial
|
|||||||
sudo: required
|
sudo: required
|
||||||
jobs:
|
jobs:
|
||||||
include:
|
include:
|
||||||
|
- name: Run plugin test suite with python 3.8
|
||||||
|
python: 3.8
|
||||||
|
script: 'pytest'
|
||||||
|
|
||||||
- name: Run plugin test suite with python 3.7
|
- name: Run plugin test suite with python 3.7
|
||||||
python: 3.7
|
python: 3.7
|
||||||
script: 'pytest'
|
script: 'pytest'
|
||||||
|
|
||||||
|
- name: Typecheck Django 3.0 test suite with python 3.8
|
||||||
|
python: 3.8
|
||||||
|
script: |
|
||||||
|
python ./scripts/typecheck_tests.py --django_version=3.0
|
||||||
|
|
||||||
- name: Typecheck Django 3.0 test suite with python 3.7
|
- name: Typecheck Django 3.0 test suite with python 3.7
|
||||||
python: 3.7
|
python: 3.7
|
||||||
script: |
|
script: |
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ We rely on different `django` and `mypy` versions:
|
|||||||
|
|
||||||
| django-stubs | mypy version | django version | python version
|
| django-stubs | mypy version | django version | python version
|
||||||
| ------------ | ---- | ---- | ---- |
|
| ------------ | ---- | ---- | ---- |
|
||||||
| 1.3.0 | 0.750 | 2.2.x | ^3.6
|
| 1.5.0 | 0.780 | 2.2.x \|\| 3.x | ^3.6
|
||||||
|
| 1.4.0 | 0.770 | 2.2.x \|\| 3.x | ^3.6
|
||||||
|
| 1.3.0 | 0.750 | 2.2.x \|\| 3.x | ^3.6
|
||||||
| 1.2.0 | 0.730 | 2.2.x | ^3.6
|
| 1.2.0 | 0.730 | 2.2.x | ^3.6
|
||||||
| 1.1.0 | 0.720 | 2.2.x | ^3.6
|
| 1.1.0 | 0.720 | 2.2.x | ^3.6
|
||||||
| 0.12.x | old semantic analyzer (<0.711), dmypy support | 2.1.x | ^3.6
|
| 0.12.x | old semantic analyzer (<0.711), dmypy support | 2.1.x | ^3.6
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
black
|
black
|
||||||
pytest-mypy-plugins==1.2.0
|
pytest-mypy-plugins==1.3.0
|
||||||
psycopg2
|
psycopg2
|
||||||
flake8==3.7.9
|
flake8==3.7.9
|
||||||
flake8-pyi==19.3.0
|
flake8-pyi==19.3.0
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple, Union, Iterable
|
from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple, Union, Iterable
|
||||||
|
|
||||||
from django.contrib.auth.forms import AdminPasswordChangeForm
|
|
||||||
from django.forms.boundfield import BoundField
|
from django.forms.boundfield import BoundField
|
||||||
|
from django.forms.forms import BaseForm
|
||||||
from django.forms.utils import ErrorDict
|
from django.forms.utils import ErrorDict
|
||||||
from django.forms.widgets import Media, Widget
|
from django.forms.widgets import Media, Widget
|
||||||
from django.utils.safestring import SafeText
|
from django.utils.safestring import SafeText
|
||||||
@@ -23,7 +23,7 @@ class AdminForm:
|
|||||||
readonly_fields: Any = ...
|
readonly_fields: Any = ...
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
form: AdminPasswordChangeForm,
|
form: BaseForm,
|
||||||
fieldsets: List[Tuple[None, Dict[str, List[str]]]],
|
fieldsets: List[Tuple[None, Dict[str, List[str]]]],
|
||||||
prepopulated_fields: Dict[Any, Any],
|
prepopulated_fields: Dict[Any, Any],
|
||||||
readonly_fields: Optional[Iterable[Any]] = ...,
|
readonly_fields: Optional[Iterable[Any]] = ...,
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from typing import Any, Callable, Dict, Iterator, List, Optional, Sequence, Set, Tuple, Type, Union
|
from typing import Any, Callable, Dict, Iterator, List, Optional, Sequence, Set, Tuple, Type, Union, Mapping, TypeVar
|
||||||
|
|
||||||
|
from django.forms.forms import BaseForm
|
||||||
|
from django.forms.formsets import BaseFormSet
|
||||||
|
from typing_extensions import Literal, TypedDict
|
||||||
|
|
||||||
from django.contrib.admin.filters import ListFilter
|
from django.contrib.admin.filters import ListFilter
|
||||||
from django.contrib.admin.models import LogEntry
|
from django.contrib.admin.models import LogEntry
|
||||||
@@ -26,8 +30,10 @@ from django.db.models.fields import Field
|
|||||||
|
|
||||||
IS_POPUP_VAR: str
|
IS_POPUP_VAR: str
|
||||||
TO_FIELD_VAR: str
|
TO_FIELD_VAR: str
|
||||||
HORIZONTAL: Any
|
HORIZONTAL: Literal[1] = ...
|
||||||
VERTICAL: Any
|
VERTICAL: Literal[2] = ...
|
||||||
|
|
||||||
|
_Direction = Union[Literal[1], Literal[2]]
|
||||||
|
|
||||||
def get_content_type_for_model(obj: Union[Type[Model], Model]) -> ContentType: ...
|
def get_content_type_for_model(obj: Union[Type[Model], Model]) -> ContentType: ...
|
||||||
def get_ul_class(radio_style: int) -> str: ...
|
def get_ul_class(radio_style: int) -> str: ...
|
||||||
@@ -37,21 +43,35 @@ class IncorrectLookupParameters(Exception): ...
|
|||||||
FORMFIELD_FOR_DBFIELD_DEFAULTS: Any
|
FORMFIELD_FOR_DBFIELD_DEFAULTS: Any
|
||||||
csrf_protect_m: Any
|
csrf_protect_m: Any
|
||||||
|
|
||||||
|
class _OptionalFieldOpts(TypedDict, total=False):
|
||||||
|
classes: Sequence[str]
|
||||||
|
description: str
|
||||||
|
|
||||||
|
class _FieldOpts(_OptionalFieldOpts, total=True):
|
||||||
|
fields: Sequence[Union[str, Sequence[str]]]
|
||||||
|
|
||||||
|
# Workaround for mypy issue, a Sequence type should be preferred here.
|
||||||
|
# https://github.com/python/mypy/issues/8921
|
||||||
|
# _FieldsetSpec = Sequence[Tuple[Optional[str], _FieldOpts]]
|
||||||
|
_T = TypeVar("_T")
|
||||||
|
_ListOrTuple = Union[Tuple[_T, ...], List[_T]]
|
||||||
|
_FieldsetSpec = _ListOrTuple[Tuple[Optional[str], _FieldOpts]]
|
||||||
|
|
||||||
class BaseModelAdmin:
|
class BaseModelAdmin:
|
||||||
autocomplete_fields: Any = ...
|
autocomplete_fields: Sequence[str] = ...
|
||||||
raw_id_fields: Any = ...
|
raw_id_fields: Sequence[str] = ...
|
||||||
fields: Any = ...
|
fields: Sequence[Union[str, Sequence[str]]] = ...
|
||||||
exclude: Any = ...
|
exclude: Sequence[str] = ...
|
||||||
fieldsets: Any = ...
|
fieldsets: _FieldsetSpec = ...
|
||||||
form: Any = ...
|
form: Type[BaseForm] = ...
|
||||||
filter_vertical: Any = ...
|
filter_vertical: Sequence[str] = ...
|
||||||
filter_horizontal: Any = ...
|
filter_horizontal: Sequence[str] = ...
|
||||||
radio_fields: Any = ...
|
radio_fields: Mapping[str, _Direction] = ...
|
||||||
prepopulated_fields: Any = ...
|
prepopulated_fields: Mapping[str, Sequence[str]] = ...
|
||||||
formfield_overrides: Any = ...
|
formfield_overrides: Mapping[Type[Field], Mapping[str, Any]] = ...
|
||||||
readonly_fields: Any = ...
|
readonly_fields: Sequence[Union[str, Callable[[Model], Any]]] = ...
|
||||||
ordering: Any = ...
|
ordering: Sequence[str] = ...
|
||||||
sortable_by: Any = ...
|
sortable_by: Sequence[str] = ...
|
||||||
view_on_site: bool = ...
|
view_on_site: bool = ...
|
||||||
show_full_result_count: bool = ...
|
show_full_result_count: bool = ...
|
||||||
checks_class: Any = ...
|
checks_class: Any = ...
|
||||||
@@ -93,7 +113,7 @@ class BaseModelAdmin:
|
|||||||
def has_module_permission(self, request: HttpRequest) -> bool: ...
|
def has_module_permission(self, request: HttpRequest) -> bool: ...
|
||||||
|
|
||||||
class ModelAdmin(BaseModelAdmin):
|
class ModelAdmin(BaseModelAdmin):
|
||||||
list_display: Sequence[Union[str, Callable]] = ...
|
list_display: Sequence[Union[str, Callable[[Model], Any]]] = ...
|
||||||
list_display_links: Optional[Sequence[Union[str, Callable]]] = ...
|
list_display_links: Optional[Sequence[Union[str, Callable]]] = ...
|
||||||
list_filter: Sequence[Union[str, Type[ListFilter], Tuple[str, Type[ListFilter]]]] = ...
|
list_filter: Sequence[Union[str, Type[ListFilter], Tuple[str, Type[ListFilter]]]] = ...
|
||||||
list_select_related: Union[bool, Sequence[str]] = ...
|
list_select_related: Union[bool, Sequence[str]] = ...
|
||||||
@@ -101,21 +121,21 @@ class ModelAdmin(BaseModelAdmin):
|
|||||||
list_max_show_all: int = ...
|
list_max_show_all: int = ...
|
||||||
list_editable: Sequence[str] = ...
|
list_editable: Sequence[str] = ...
|
||||||
search_fields: Sequence[str] = ...
|
search_fields: Sequence[str] = ...
|
||||||
date_hierarchy: Optional[Any] = ...
|
date_hierarchy: Optional[str] = ...
|
||||||
save_as: bool = ...
|
save_as: bool = ...
|
||||||
save_as_continue: bool = ...
|
save_as_continue: bool = ...
|
||||||
save_on_top: bool = ...
|
save_on_top: bool = ...
|
||||||
paginator: Any = ...
|
paginator: Type = ...
|
||||||
preserve_filters: bool = ...
|
preserve_filters: bool = ...
|
||||||
inlines: Sequence[Type[InlineModelAdmin]] = ...
|
inlines: Sequence[Type[InlineModelAdmin]] = ...
|
||||||
add_form_template: Any = ...
|
add_form_template: str = ...
|
||||||
change_form_template: Any = ...
|
change_form_template: str = ...
|
||||||
change_list_template: Any = ...
|
change_list_template: str = ...
|
||||||
delete_confirmation_template: Any = ...
|
delete_confirmation_template: str = ...
|
||||||
delete_selected_confirmation_template: Any = ...
|
delete_selected_confirmation_template: str = ...
|
||||||
object_history_template: Any = ...
|
object_history_template: str = ...
|
||||||
popup_response_template: Any = ...
|
popup_response_template: str = ...
|
||||||
actions: Any = ...
|
actions: Sequence[Callable[[ModelAdmin, HttpRequest, QuerySet], None]] = ...
|
||||||
action_form: Any = ...
|
action_form: Any = ...
|
||||||
actions_on_top: bool = ...
|
actions_on_top: bool = ...
|
||||||
actions_on_bottom: bool = ...
|
actions_on_bottom: bool = ...
|
||||||
@@ -227,9 +247,9 @@ class ModelAdmin(BaseModelAdmin):
|
|||||||
def history_view(self, request: HttpRequest, object_id: str, extra_context: None = ...) -> HttpResponse: ...
|
def history_view(self, request: HttpRequest, object_id: str, extra_context: None = ...) -> HttpResponse: ...
|
||||||
|
|
||||||
class InlineModelAdmin(BaseModelAdmin):
|
class InlineModelAdmin(BaseModelAdmin):
|
||||||
model: Any = ...
|
model: Type[Model] = ...
|
||||||
fk_name: Any = ...
|
fk_name: str = ...
|
||||||
formset: Any = ...
|
formset: BaseFormSet = ...
|
||||||
extra: int = ...
|
extra: int = ...
|
||||||
min_num: Optional[int] = ...
|
min_num: Optional[int] = ...
|
||||||
max_num: Optional[int] = ...
|
max_num: Optional[int] = ...
|
||||||
@@ -238,8 +258,8 @@ class InlineModelAdmin(BaseModelAdmin):
|
|||||||
verbose_name_plural: Optional[str] = ...
|
verbose_name_plural: Optional[str] = ...
|
||||||
can_delete: bool = ...
|
can_delete: bool = ...
|
||||||
show_change_link: bool = ...
|
show_change_link: bool = ...
|
||||||
classes: Any = ...
|
classes: Optional[Sequence[str]] = ...
|
||||||
admin_site: Any = ...
|
admin_site: AdminSite = ...
|
||||||
parent_model: Any = ...
|
parent_model: Any = ...
|
||||||
opts: Any = ...
|
opts: Any = ...
|
||||||
has_registered_model: Any = ...
|
has_registered_model: Any = ...
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class AdminSite:
|
|||||||
def i18n_javascript(self, request: WSGIRequest, extra_context: Optional[Dict[Any, Any]] = ...) -> HttpResponse: ...
|
def i18n_javascript(self, request: WSGIRequest, extra_context: Optional[Dict[Any, Any]] = ...) -> HttpResponse: ...
|
||||||
def logout(self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ...) -> TemplateResponse: ...
|
def logout(self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ...) -> TemplateResponse: ...
|
||||||
def login(self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ...) -> HttpResponse: ...
|
def login(self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ...) -> HttpResponse: ...
|
||||||
|
def _build_app_dict(self, request: WSGIRequest, label: Optional[str] = ...) -> Dict[str, Any]: ...
|
||||||
def get_app_list(self, request: WSGIRequest) -> List[Any]: ...
|
def get_app_list(self, request: WSGIRequest) -> List[Any]: ...
|
||||||
def index(self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ...) -> TemplateResponse: ...
|
def index(self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ...) -> TemplateResponse: ...
|
||||||
def app_index(
|
def app_index(
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
|
import sys
|
||||||
from typing import Any, Optional, Tuple, List, overload, TypeVar
|
from typing import Any, Optional, Tuple, List, overload, TypeVar
|
||||||
|
|
||||||
from django.db.models.base import Model
|
from django.db.models.base import Model
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
if sys.version_info < (3, 8):
|
||||||
|
from typing_extensions import Literal
|
||||||
|
else:
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
_T = TypeVar("_T", bound=Model)
|
_T = TypeVar("_T", bound=Model)
|
||||||
|
|
||||||
class BaseUserManager(models.Manager[_T]):
|
class BaseUserManager(models.Manager[_T]):
|
||||||
@@ -20,9 +26,9 @@ class AbstractBaseUser(models.Model):
|
|||||||
def get_username(self) -> str: ...
|
def get_username(self) -> str: ...
|
||||||
def natural_key(self) -> Tuple[str]: ...
|
def natural_key(self) -> Tuple[str]: ...
|
||||||
@property
|
@property
|
||||||
def is_anonymous(self) -> bool: ...
|
def is_anonymous(self) -> Literal[False]: ...
|
||||||
@property
|
@property
|
||||||
def is_authenticated(self) -> bool: ...
|
def is_authenticated(self) -> Literal[True]: ...
|
||||||
def set_password(self, raw_password: Optional[str]) -> None: ...
|
def set_password(self, raw_password: Optional[str]) -> None: ...
|
||||||
def check_password(self, raw_password: str) -> bool: ...
|
def check_password(self, raw_password: str) -> bool: ...
|
||||||
def set_unusable_password(self) -> None: ...
|
def set_unusable_password(self) -> None: ...
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import sys
|
||||||
from typing import Any, Collection, Optional, Set, Tuple, Type, TypeVar, Union
|
from typing import Any, Collection, Optional, Set, Tuple, Type, TypeVar, Union
|
||||||
|
|
||||||
from django.contrib.auth.backends import ModelBackend
|
from django.contrib.auth.backends import ModelBackend
|
||||||
@@ -9,6 +10,11 @@ from django.db.models.manager import EmptyManager
|
|||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
if sys.version_info < (3, 8):
|
||||||
|
from typing_extensions import Literal
|
||||||
|
else:
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
_AnyUser = Union[Model, "AnonymousUser"]
|
_AnyUser = Union[Model, "AnonymousUser"]
|
||||||
|
|
||||||
def update_last_login(sender: Type[AbstractBaseUser], user: AbstractBaseUser, **kwargs: Any) -> None: ...
|
def update_last_login(sender: Type[AbstractBaseUser], user: AbstractBaseUser, **kwargs: Any) -> None: ...
|
||||||
@@ -105,7 +111,7 @@ class AnonymousUser:
|
|||||||
def has_perms(self, perm_list: Collection[str], obj: Optional[_AnyUser] = ...) -> bool: ...
|
def has_perms(self, perm_list: Collection[str], obj: Optional[_AnyUser] = ...) -> bool: ...
|
||||||
def has_module_perms(self, module: str) -> bool: ...
|
def has_module_perms(self, module: str) -> bool: ...
|
||||||
@property
|
@property
|
||||||
def is_anonymous(self) -> bool: ...
|
def is_anonymous(self) -> Literal[True]: ...
|
||||||
@property
|
@property
|
||||||
def is_authenticated(self) -> bool: ...
|
def is_authenticated(self) -> Literal[False]: ...
|
||||||
def get_username(self) -> str: ...
|
def get_username(self) -> str: ...
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any, Dict, List, Optional, Union
|
from typing import Any, Dict, List, Optional, Union, Protocol
|
||||||
|
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.contrib.sites.requests import RequestSite
|
from django.contrib.sites.requests import RequestSite
|
||||||
@@ -13,10 +13,19 @@ class SitemapNotFound(Exception): ...
|
|||||||
|
|
||||||
def ping_google(sitemap_url: Optional[str] = ..., ping_url: str = ...) -> None: ...
|
def ping_google(sitemap_url: Optional[str] = ..., ping_url: str = ...) -> None: ...
|
||||||
|
|
||||||
|
class _SupportsLen(Protocol):
|
||||||
|
def __len__(self) -> int: ...
|
||||||
|
|
||||||
|
class _SupportsCount(Protocol):
|
||||||
|
def count(self) -> int: ...
|
||||||
|
|
||||||
|
class _SupportsOrdered(Protocol):
|
||||||
|
ordered: bool = ...
|
||||||
|
|
||||||
class Sitemap:
|
class Sitemap:
|
||||||
limit: int = ...
|
limit: int = ...
|
||||||
protocol: Optional[str] = ...
|
protocol: Optional[str] = ...
|
||||||
def items(self) -> List[Any]: ...
|
def items(self) -> Union[_SupportsLen, _SupportsCount, _SupportsOrdered]: ...
|
||||||
def location(self, obj: Model) -> str: ...
|
def location(self, obj: Model) -> str: ...
|
||||||
@property
|
@property
|
||||||
def paginator(self) -> Paginator: ...
|
def paginator(self) -> Paginator: ...
|
||||||
|
|||||||
6
django-stubs/core/cache/backends/base.pyi
vendored
6
django-stubs/core/cache/backends/base.pyi
vendored
@@ -19,16 +19,16 @@ class BaseCache:
|
|||||||
def __init__(self, params: Dict[str, Any]) -> None: ...
|
def __init__(self, params: Dict[str, Any]) -> None: ...
|
||||||
def get_backend_timeout(self, timeout: Any = ...) -> Optional[float]: ...
|
def get_backend_timeout(self, timeout: Any = ...) -> Optional[float]: ...
|
||||||
def make_key(self, key: Any, version: Optional[Any] = ...) -> str: ...
|
def make_key(self, key: Any, version: Optional[Any] = ...) -> str: ...
|
||||||
def add(self, key: Any, value: Any, timeout: Any = ..., version: Optional[Any] = ...) -> None: ...
|
def add(self, key: Any, value: Any, timeout: Any = ..., version: Optional[Any] = ...) -> bool: ...
|
||||||
def get(self, key: Any, default: Optional[Any] = ..., version: Optional[Any] = ...) -> Any: ...
|
def get(self, key: Any, default: Optional[Any] = ..., version: Optional[Any] = ...) -> Any: ...
|
||||||
def set(self, key: Any, value: Any, timeout: Any = ..., version: Optional[Any] = ...) -> None: ...
|
def set(self, key: Any, value: Any, timeout: Any = ..., version: Optional[Any] = ...) -> None: ...
|
||||||
def touch(self, key: Any, timeout: Any = ..., version: Optional[Any] = ...) -> None: ...
|
def touch(self, key: Any, timeout: Any = ..., version: Optional[Any] = ...) -> bool: ...
|
||||||
def delete(self, key: Any, version: Optional[Any] = ...) -> None: ...
|
def delete(self, key: Any, version: Optional[Any] = ...) -> None: ...
|
||||||
def get_many(self, keys: List[str], version: Optional[int] = ...) -> Dict[str, Union[int, str]]: ...
|
def get_many(self, keys: List[str], version: Optional[int] = ...) -> Dict[str, Union[int, str]]: ...
|
||||||
def get_or_set(
|
def get_or_set(
|
||||||
self, key: Any, default: Optional[Any], timeout: Any = ..., version: Optional[int] = ...
|
self, key: Any, default: Optional[Any], timeout: Any = ..., version: Optional[int] = ...
|
||||||
) -> Optional[Any]: ...
|
) -> Optional[Any]: ...
|
||||||
def has_key(self, key: Any, version: Optional[Any] = ...): ...
|
def has_key(self, key: Any, version: Optional[Any] = ...) -> bool: ...
|
||||||
def incr(self, key: str, delta: int = ..., version: Optional[int] = ...) -> int: ...
|
def incr(self, key: str, delta: int = ..., version: Optional[int] = ...) -> int: ...
|
||||||
def decr(self, key: str, delta: int = ..., version: Optional[int] = ...) -> int: ...
|
def decr(self, key: str, delta: int = ..., version: Optional[int] = ...) -> int: ...
|
||||||
def __contains__(self, key: str) -> bool: ...
|
def __contains__(self, key: str) -> bool: ...
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ class SkipFile(UploadFileException): ...
|
|||||||
class StopFutureHandlers(UploadFileException): ...
|
class StopFutureHandlers(UploadFileException): ...
|
||||||
|
|
||||||
class FileUploadHandler:
|
class FileUploadHandler:
|
||||||
chunk_size = ... # type: int
|
chunk_size: int = ...
|
||||||
file_name = ... # type: Optional[str]
|
file_name: Optional[str] = ...
|
||||||
content_type = ... # type: Optional[str]
|
content_type: Optional[str] = ...
|
||||||
content_length = ... # type: Optional[int]
|
content_length: Optional[int] = ...
|
||||||
charset = ... # type: Optional[str]
|
charset: Optional[str] = ...
|
||||||
content_type_extra = ... # type: Optional[Dict[str, str]]
|
content_type_extra: Optional[Dict[str, str]] = ...
|
||||||
request = ... # type: Optional[HttpRequest]
|
request: Optional[HttpRequest] = ...
|
||||||
field_name = ... # type: str
|
field_name: str = ...
|
||||||
def __init__(self, request: Optional[HttpRequest] = ...) -> None: ...
|
def __init__(self, request: Optional[HttpRequest] = ...) -> None: ...
|
||||||
def handle_raw_input(
|
def handle_raw_input(
|
||||||
self,
|
self,
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Any, Callable, Dict, Optional, Union
|
from typing import Any, Callable, Dict, Optional, Union
|
||||||
|
|
||||||
from django.contrib.auth.models import AbstractUser
|
|
||||||
from django.contrib.sessions.backends.base import SessionBase
|
from django.contrib.sessions.backends.base import SessionBase
|
||||||
from django.http.response import HttpResponse
|
|
||||||
|
|
||||||
from django.core.handlers import base
|
from django.core.handlers import base
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
|
from django.http.response import HttpResponse
|
||||||
|
|
||||||
_Stream = Union[BytesIO, str]
|
_Stream = Union[BytesIO, str]
|
||||||
_WSGIEnviron = Dict[str, Any]
|
_WSGIEnviron = Dict[str, Any]
|
||||||
@@ -22,7 +20,6 @@ class LimitedStream:
|
|||||||
|
|
||||||
class WSGIRequest(HttpRequest):
|
class WSGIRequest(HttpRequest):
|
||||||
environ: _WSGIEnviron = ...
|
environ: _WSGIEnviron = ...
|
||||||
user: AbstractUser
|
|
||||||
session: SessionBase
|
session: SessionBase
|
||||||
encoding: Any = ...
|
encoding: Any = ...
|
||||||
def __init__(self, environ: _WSGIEnviron) -> None: ...
|
def __init__(self, environ: _WSGIEnviron) -> None: ...
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ class InvalidPage(Exception): ...
|
|||||||
class PageNotAnInteger(InvalidPage): ...
|
class PageNotAnInteger(InvalidPage): ...
|
||||||
class EmptyPage(InvalidPage): ...
|
class EmptyPage(InvalidPage): ...
|
||||||
|
|
||||||
class SupportsLen(Protocol):
|
class _SupportsLen(Protocol):
|
||||||
def __len__(self) -> int: ...
|
def __len__(self) -> int: ...
|
||||||
|
|
||||||
class SupportsCount(Protocol):
|
class _SupportsCount(Protocol):
|
||||||
def count(self) -> int: ...
|
def count(self) -> int: ...
|
||||||
|
|
||||||
class SupportsOrdered(Protocol):
|
class _SupportsOrdered(Protocol):
|
||||||
ordered: bool = ...
|
ordered: bool = ...
|
||||||
|
|
||||||
class Paginator:
|
class Paginator:
|
||||||
@@ -24,7 +24,7 @@ class Paginator:
|
|||||||
allow_empty_first_page: bool = ...
|
allow_empty_first_page: bool = ...
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
object_list: Union[SupportsLen, SupportsCount, SupportsOrdered],
|
object_list: Union[_SupportsLen, _SupportsCount, _SupportsOrdered],
|
||||||
per_page: Union[int, str],
|
per_page: Union[int, str],
|
||||||
orphans: int = ...,
|
orphans: int = ...,
|
||||||
allow_empty_first_page: bool = ...,
|
allow_empty_first_page: bool = ...,
|
||||||
|
|||||||
@@ -68,6 +68,9 @@ from .deletion import (
|
|||||||
DO_NOTHING as DO_NOTHING,
|
DO_NOTHING as DO_NOTHING,
|
||||||
PROTECT as PROTECT,
|
PROTECT as PROTECT,
|
||||||
SET as SET,
|
SET as SET,
|
||||||
|
RESTRICT as RESTRICT,
|
||||||
|
ProtectedError as ProtectedError,
|
||||||
|
RestrictedError as RestrictedError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .query import (
|
from .query import (
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Tuple, Type, TypeVar, Union, Collection
|
from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Tuple, Type, TypeVar, Union, Collection, ClassVar
|
||||||
|
|
||||||
from django.core.checks.messages import CheckMessage
|
from django.core.checks.messages import CheckMessage
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
@@ -7,6 +7,13 @@ from django.db.models.options import Options
|
|||||||
|
|
||||||
_Self = TypeVar("_Self", bound="Model")
|
_Self = TypeVar("_Self", bound="Model")
|
||||||
|
|
||||||
|
class ModelStateFieldsCacheDescriptor: ...
|
||||||
|
|
||||||
|
class ModelState:
|
||||||
|
db: Optional[str] = ...
|
||||||
|
adding: bool = ...
|
||||||
|
fields_cache: ModelStateFieldsCacheDescriptor = ...
|
||||||
|
|
||||||
class ModelBase(type): ...
|
class ModelBase(type): ...
|
||||||
|
|
||||||
class Model(metaclass=ModelBase):
|
class Model(metaclass=ModelBase):
|
||||||
@@ -15,9 +22,14 @@ class Model(metaclass=ModelBase):
|
|||||||
class Meta: ...
|
class Meta: ...
|
||||||
_meta: Options[Any]
|
_meta: Options[Any]
|
||||||
_default_manager: BaseManager[Model]
|
_default_manager: BaseManager[Model]
|
||||||
objects: BaseManager[Any]
|
objects: ClassVar[BaseManager[Any]]
|
||||||
pk: Any = ...
|
pk: Any = ...
|
||||||
|
_state: ModelState
|
||||||
def __init__(self: _Self, *args, **kwargs) -> None: ...
|
def __init__(self: _Self, *args, **kwargs) -> None: ...
|
||||||
|
@classmethod
|
||||||
|
def add_to_class(cls, name: str, value: Any): ...
|
||||||
|
@classmethod
|
||||||
|
def from_db(cls, db: Optional[str], field_names: Collection[str], values: Collection[Any]) -> _Self: ...
|
||||||
def delete(self, using: Any = ..., keep_parents: bool = ...) -> Tuple[int, Dict[str, int]]: ...
|
def delete(self, using: Any = ..., keep_parents: bool = ...) -> Tuple[int, Dict[str, int]]: ...
|
||||||
def full_clean(self, exclude: Optional[Collection[str]] = ..., validate_unique: bool = ...) -> None: ...
|
def full_clean(self, exclude: Optional[Collection[str]] = ..., validate_unique: bool = ...) -> None: ...
|
||||||
def clean(self) -> None: ...
|
def clean(self) -> None: ...
|
||||||
@@ -46,10 +58,3 @@ class Model(metaclass=ModelBase):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def check(cls, **kwargs: Any) -> List[CheckMessage]: ...
|
def check(cls, **kwargs: Any) -> List[CheckMessage]: ...
|
||||||
def __getstate__(self) -> dict: ...
|
def __getstate__(self) -> dict: ...
|
||||||
|
|
||||||
class ModelStateFieldsCacheDescriptor: ...
|
|
||||||
|
|
||||||
class ModelState:
|
|
||||||
db: None = ...
|
|
||||||
adding: bool = ...
|
|
||||||
fields_cache: ModelStateFieldsCacheDescriptor = ...
|
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ def SET_NULL(collector, field, sub_objs, using): ...
|
|||||||
def SET_DEFAULT(collector, field, sub_objs, using): ...
|
def SET_DEFAULT(collector, field, sub_objs, using): ...
|
||||||
def DO_NOTHING(collector, field, sub_objs, using): ...
|
def DO_NOTHING(collector, field, sub_objs, using): ...
|
||||||
def PROTECT(collector, field, sub_objs, using): ...
|
def PROTECT(collector, field, sub_objs, using): ...
|
||||||
|
def RESTRICT(collector, field, sub_objs, using): ...
|
||||||
def SET(value: Any) -> Callable: ...
|
def SET(value: Any) -> Callable: ...
|
||||||
def get_candidate_relations_to_delete(opts: Options) -> Iterable[Field]: ...
|
def get_candidate_relations_to_delete(opts: Options) -> Iterable[Field]: ...
|
||||||
|
|
||||||
class ProtectedError(IntegrityError): ...
|
class ProtectedError(IntegrityError): ...
|
||||||
|
class RestrictedError(IntegrityError): ...
|
||||||
|
|
||||||
class Collector:
|
class Collector:
|
||||||
def __init__(self, using: str) -> None: ...
|
def __init__(self, using: str) -> None: ...
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
from typing import Any, Dict, Iterator, List, Mapping, Optional, Sequence, Type, Union
|
from typing import Any, Dict, Iterator, List, Mapping, Optional, Sequence, Type, Union
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError as ValidationError
|
from django.core.exceptions import ValidationError as ValidationError
|
||||||
|
from django.core.files import uploadedfile
|
||||||
from django.forms.boundfield import BoundField
|
from django.forms.boundfield import BoundField
|
||||||
from django.forms.fields import Field
|
from django.forms.fields import Field
|
||||||
from django.forms.renderers import BaseRenderer
|
from django.forms.renderers import BaseRenderer
|
||||||
from django.forms.utils import ErrorDict, ErrorList
|
from django.forms.utils import ErrorDict, ErrorList
|
||||||
from django.forms.widgets import Media, MediaDefiningClass
|
from django.forms.widgets import Media, MediaDefiningClass
|
||||||
|
from django.utils.datastructures import MultiValueDict
|
||||||
from django.utils.safestring import SafeText
|
from django.utils.safestring import SafeText
|
||||||
|
|
||||||
class DeclarativeFieldsMetaclass(MediaDefiningClass): ...
|
class DeclarativeFieldsMetaclass(MediaDefiningClass): ...
|
||||||
@@ -18,11 +20,11 @@ class BaseForm:
|
|||||||
use_required_attribute: bool = ...
|
use_required_attribute: bool = ...
|
||||||
is_bound: bool = ...
|
is_bound: bool = ...
|
||||||
data: Dict[str, Any] = ...
|
data: Dict[str, Any] = ...
|
||||||
files: Optional[Dict[str, Any]] = ...
|
files: MultiValueDict[str, uploadedfile.UploadedFile] = ...
|
||||||
auto_id: str = ...
|
auto_id: Union[bool, str] = ...
|
||||||
initial: Dict[str, Any] = ...
|
initial: Dict[str, Any] = ...
|
||||||
error_class: Type[ErrorList] = ...
|
error_class: Type[ErrorList] = ...
|
||||||
prefix: str = ...
|
prefix: Optional[str] = ...
|
||||||
label_suffix: str = ...
|
label_suffix: str = ...
|
||||||
empty_permitted: bool = ...
|
empty_permitted: bool = ...
|
||||||
fields: Dict[str, Any] = ...
|
fields: Dict[str, Any] = ...
|
||||||
@@ -67,6 +69,9 @@ class BaseForm:
|
|||||||
def hidden_fields(self): ...
|
def hidden_fields(self): ...
|
||||||
def visible_fields(self): ...
|
def visible_fields(self): ...
|
||||||
def get_initial_for_field(self, field: Field, field_name: str) -> Any: ...
|
def get_initial_for_field(self, field: Field, field_name: str) -> Any: ...
|
||||||
|
def _html_output(
|
||||||
|
self, normal_row: str, error_row: str, row_ender: str, help_text_html: str, errors_on_separate_row: bool,
|
||||||
|
) -> SafeText: ...
|
||||||
|
|
||||||
class Form(BaseForm):
|
class Form(BaseForm):
|
||||||
base_fields: Dict[str, Field]
|
base_fields: Dict[str, Field]
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from typing import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from django.contrib.auth.base_user import AbstractBaseUser
|
from django.contrib.auth.base_user import AbstractBaseUser
|
||||||
|
from django.contrib.auth.models import AnonymousUser
|
||||||
from django.contrib.sessions.backends.base import SessionBase
|
from django.contrib.sessions.backends.base import SessionBase
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.utils.datastructures import CaseInsensitiveMapping, ImmutableList, MultiValueDict
|
from django.utils.datastructures import CaseInsensitiveMapping, ImmutableList, MultiValueDict
|
||||||
@@ -51,7 +52,7 @@ class HttpRequest(BytesIO):
|
|||||||
resolver_match: ResolverMatch = ...
|
resolver_match: ResolverMatch = ...
|
||||||
content_type: Optional[str] = ...
|
content_type: Optional[str] = ...
|
||||||
content_params: Optional[Dict[str, str]] = ...
|
content_params: Optional[Dict[str, str]] = ...
|
||||||
user: AbstractBaseUser
|
user: Union[AbstractBaseUser, AnonymousUser]
|
||||||
site: Site
|
site: Site
|
||||||
session: SessionBase
|
session: SessionBase
|
||||||
encoding: Optional[str] = ...
|
encoding: Optional[str] = ...
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from typing import Any, Callable, Dict, List, Optional, Protocol, Sequence, Type, TypeVar, Union
|
import sys
|
||||||
|
from typing import Any, Callable, List, Mapping, Optional, overload, Protocol, Sequence, Type, TypeVar, Union
|
||||||
|
|
||||||
from django.db.models.base import Model
|
from django.db.models.base import Model
|
||||||
from django.http.response import (
|
from django.http.response import (
|
||||||
@@ -10,9 +11,14 @@ from django.http.response import (
|
|||||||
from django.db.models import Manager, QuerySet
|
from django.db.models import Manager, QuerySet
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
|
|
||||||
|
if sys.version_info < (3, 8):
|
||||||
|
from typing_extensions import Literal
|
||||||
|
else:
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
def render_to_response(
|
def render_to_response(
|
||||||
template_name: Union[str, Sequence[str]],
|
template_name: Union[str, Sequence[str]],
|
||||||
context: Optional[Dict[str, Any]] = ...,
|
context: Optional[Mapping[str, Any]] = ...,
|
||||||
content_type: Optional[str] = ...,
|
content_type: Optional[str] = ...,
|
||||||
status: Optional[int] = ...,
|
status: Optional[int] = ...,
|
||||||
using: Optional[str] = ...,
|
using: Optional[str] = ...,
|
||||||
@@ -20,7 +26,7 @@ def render_to_response(
|
|||||||
def render(
|
def render(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
template_name: Union[str, Sequence[str]],
|
template_name: Union[str, Sequence[str]],
|
||||||
context: Optional[Dict[str, Any]] = ...,
|
context: Optional[Mapping[str, Any]] = ...,
|
||||||
content_type: Optional[str] = ...,
|
content_type: Optional[str] = ...,
|
||||||
status: Optional[int] = ...,
|
status: Optional[int] = ...,
|
||||||
using: Optional[str] = ...,
|
using: Optional[str] = ...,
|
||||||
@@ -28,6 +34,15 @@ def render(
|
|||||||
|
|
||||||
class SupportsGetAbsoluteUrl(Protocol): ...
|
class SupportsGetAbsoluteUrl(Protocol): ...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def redirect(
|
||||||
|
to: Union[Callable, str, SupportsGetAbsoluteUrl], *args: Any, permanent: Literal[True], **kwargs: Any
|
||||||
|
) -> HttpResponsePermanentRedirect: ...
|
||||||
|
@overload
|
||||||
|
def redirect(
|
||||||
|
to: Union[Callable, str, SupportsGetAbsoluteUrl], *args: Any, permanent: Literal[False], **kwargs: Any
|
||||||
|
) -> HttpResponseRedirect: ...
|
||||||
|
@overload
|
||||||
def redirect(
|
def redirect(
|
||||||
to: Union[Callable, str, SupportsGetAbsoluteUrl], *args: Any, permanent: bool = ..., **kwargs: Any
|
to: Union[Callable, str, SupportsGetAbsoluteUrl], *args: Any, permanent: bool = ..., **kwargs: Any
|
||||||
) -> Union[HttpResponseRedirect, HttpResponsePermanentRedirect]: ...
|
) -> Union[HttpResponseRedirect, HttpResponsePermanentRedirect]: ...
|
||||||
|
|||||||
@@ -126,9 +126,17 @@ class SimpleTestCase(unittest.TestCase):
|
|||||||
self, needle: str, haystack: SafeText, count: Optional[int] = ..., msg_prefix: str = ...
|
self, needle: str, haystack: SafeText, count: Optional[int] = ..., msg_prefix: str = ...
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
def assertJSONEqual(
|
def assertJSONEqual(
|
||||||
self, raw: str, expected_data: Union[Dict[str, str], bool, str], msg: Optional[str] = ...
|
self,
|
||||||
|
raw: str,
|
||||||
|
expected_data: Union[Dict[str, Any], List[Any], str, int, float, bool, None],
|
||||||
|
msg: Optional[str] = ...,
|
||||||
|
) -> None: ...
|
||||||
|
def assertJSONNotEqual(
|
||||||
|
self,
|
||||||
|
raw: str,
|
||||||
|
expected_data: Union[Dict[str, Any], List[Any], str, int, float, bool, None],
|
||||||
|
msg: Optional[str] = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
def assertJSONNotEqual(self, raw: str, expected_data: str, msg: Optional[str] = ...) -> None: ...
|
|
||||||
def assertXMLEqual(self, xml1: str, xml2: str, msg: Optional[str] = ...) -> None: ...
|
def assertXMLEqual(self, xml1: str, xml2: str, msg: Optional[str] = ...) -> None: ...
|
||||||
def assertXMLNotEqual(self, xml1: str, xml2: str, msg: Optional[str] = ...) -> None: ...
|
def assertXMLNotEqual(self, xml1: str, xml2: str, msg: Optional[str] = ...) -> None: ...
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ _V = TypeVar("_V")
|
|||||||
|
|
||||||
class OrderedSet(MutableSet[_K]):
|
class OrderedSet(MutableSet[_K]):
|
||||||
dict: Dict[_K, None] = ...
|
dict: Dict[_K, None] = ...
|
||||||
|
def __init__(self, iterable: Optional[Iterable[_K]] = ...) -> None: ...
|
||||||
def __contains__(self, item: object) -> bool: ...
|
def __contains__(self, item: object) -> bool: ...
|
||||||
def __iter__(self) -> Iterator[_K]: ...
|
def __iter__(self) -> Iterator[_K]: ...
|
||||||
def __len__(self) -> int: ...
|
def __len__(self) -> int: ...
|
||||||
|
|||||||
@@ -13,6 +13,6 @@ NOCOLOR_PALETTE: str
|
|||||||
DARK_PALETTE: str
|
DARK_PALETTE: str
|
||||||
LIGHT_PALETTE: str
|
LIGHT_PALETTE: str
|
||||||
PALETTES: Any
|
PALETTES: Any
|
||||||
DEFAULT_PALETTE = DARK_PALETTE
|
DEFAULT_PALETTE: str = ...
|
||||||
|
|
||||||
def parse_color_setting(config_string: str) -> Optional[Dict[str, Dict[str, Union[Tuple[str], str]]]]: ...
|
def parse_color_setting(config_string: str) -> Optional[Dict[str, Dict[str, Union[Tuple[str], str]]]]: ...
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ def to_locale(language: str) -> str: ...
|
|||||||
def get_language_from_request(request: WSGIRequest, check_path: bool = ...) -> str: ...
|
def get_language_from_request(request: WSGIRequest, check_path: bool = ...) -> str: ...
|
||||||
def templatize(src: str, **kwargs: Any) -> str: ...
|
def templatize(src: str, **kwargs: Any) -> str: ...
|
||||||
def deactivate_all() -> None: ...
|
def deactivate_all() -> None: ...
|
||||||
|
def get_supported_language_variant(lang_code: str, strict: bool = ...) -> str: ...
|
||||||
def get_language_info(lang_code: str) -> Any: ...
|
def get_language_info(lang_code: str) -> Any: ...
|
||||||
|
|
||||||
from . import trans_real as trans_real
|
from . import trans_real as trans_real
|
||||||
|
|||||||
@@ -10,3 +10,5 @@ select = F401, Y
|
|||||||
max_line_length = 120
|
max_line_length = 120
|
||||||
per-file-ignores =
|
per-file-ignores =
|
||||||
*__init__.pyi: F401
|
*__init__.pyi: F401
|
||||||
|
base_user.pyi: Y003
|
||||||
|
models.pyi: Y003
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from mypy.plugin import AttributeContext
|
from mypy.plugin import AttributeContext
|
||||||
from mypy.types import Instance
|
from mypy.types import Instance
|
||||||
from mypy.types import Type as MypyType
|
from mypy.types import Type as MypyType
|
||||||
|
from mypy.types import UnionType
|
||||||
|
|
||||||
from mypy_django_plugin.django.context import DjangoContext
|
from mypy_django_plugin.django.context import DjangoContext
|
||||||
from mypy_django_plugin.lib import helpers
|
from mypy_django_plugin.lib import helpers
|
||||||
@@ -8,9 +9,18 @@ from mypy_django_plugin.lib import helpers
|
|||||||
|
|
||||||
def set_auth_user_model_as_type_for_request_user(ctx: AttributeContext, django_context: DjangoContext) -> MypyType:
|
def set_auth_user_model_as_type_for_request_user(ctx: AttributeContext, django_context: DjangoContext) -> MypyType:
|
||||||
auth_user_model = django_context.settings.AUTH_USER_MODEL
|
auth_user_model = django_context.settings.AUTH_USER_MODEL
|
||||||
model_cls = django_context.apps_registry.get_model(auth_user_model)
|
user_cls = django_context.apps_registry.get_model(auth_user_model)
|
||||||
model_info = helpers.lookup_class_typeinfo(helpers.get_typechecker_api(ctx), model_cls)
|
user_info = helpers.lookup_class_typeinfo(helpers.get_typechecker_api(ctx), user_cls)
|
||||||
if model_info is None:
|
|
||||||
|
if user_info is None:
|
||||||
return ctx.default_attr_type
|
return ctx.default_attr_type
|
||||||
|
|
||||||
return Instance(model_info, [])
|
# Imported here because django isn't properly loaded yet when module is loaded
|
||||||
|
from django.contrib.auth.models import AnonymousUser
|
||||||
|
|
||||||
|
anonymous_user_info = helpers.lookup_class_typeinfo(helpers.get_typechecker_api(ctx), AnonymousUser)
|
||||||
|
if anonymous_user_info is None:
|
||||||
|
# This shouldn't be able to happen, as we managed to import the model above...
|
||||||
|
return Instance(user_info, [])
|
||||||
|
|
||||||
|
return UnionType([Instance(user_info, []), Instance(anonymous_user_info, [])])
|
||||||
|
|||||||
@@ -185,6 +185,8 @@ IGNORED_ERRORS = {
|
|||||||
],
|
],
|
||||||
'files': [
|
'files': [
|
||||||
'Incompatible types in assignment (expression has type "IOBase", variable has type "File")',
|
'Incompatible types in assignment (expression has type "IOBase", variable has type "File")',
|
||||||
|
'Argument 1 to "TextIOWrapper" has incompatible type "File"; expected "BinaryIO"',
|
||||||
|
'Incompatible types in assignment (expression has type "BinaryIO", variable has type "File")',
|
||||||
],
|
],
|
||||||
'filtered_relation': [
|
'filtered_relation': [
|
||||||
'has no attribute "name"',
|
'has no attribute "name"',
|
||||||
@@ -378,6 +380,7 @@ IGNORED_ERRORS = {
|
|||||||
'responses': [
|
'responses': [
|
||||||
'Argument 1 to "TextIOWrapper" has incompatible type "HttpResponse"; expected "IO[bytes]"',
|
'Argument 1 to "TextIOWrapper" has incompatible type "HttpResponse"; expected "IO[bytes]"',
|
||||||
'"FileLike" has no attribute "closed"',
|
'"FileLike" has no attribute "closed"',
|
||||||
|
'Argument 1 to "TextIOWrapper" has incompatible type "HttpResponse"; expected "BinaryIO"',
|
||||||
],
|
],
|
||||||
'reverse_lookup': [
|
'reverse_lookup': [
|
||||||
"Cannot resolve keyword 'choice' into field"
|
"Cannot resolve keyword 'choice' into field"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from pytest_mypy.collect import File
|
from pytest_mypy_plugins.collect import File
|
||||||
from pytest_mypy.item import YamlTestItem
|
from pytest_mypy_plugins.item import YamlTestItem
|
||||||
|
|
||||||
|
|
||||||
def django_plugin_hook(test_item: YamlTestItem) -> None:
|
def django_plugin_hook(test_item: YamlTestItem) -> None:
|
||||||
|
|||||||
10
setup.py
10
setup.py
@@ -21,7 +21,7 @@ with open('README.md', 'r') as f:
|
|||||||
readme = f.read()
|
readme = f.read()
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
'mypy>=0.770,<0.780',
|
'mypy>=0.780,<0.790',
|
||||||
'typing-extensions',
|
'typing-extensions',
|
||||||
'django',
|
'django',
|
||||||
]
|
]
|
||||||
@@ -45,6 +45,10 @@ setup(
|
|||||||
'Development Status :: 3 - Alpha',
|
'Development Status :: 3 - Alpha',
|
||||||
'License :: OSI Approved :: MIT License',
|
'License :: OSI Approved :: MIT License',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
'Programming Language :: Python :: 3.7'
|
'Programming Language :: Python :: 3.7',
|
||||||
]
|
'Programming Language :: Python :: 3.8'
|
||||||
|
],
|
||||||
|
project_urls={
|
||||||
|
'Release notes': 'https://github.com/typeddjango/django-stubs/releases',
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
126
test-data/typecheck/contrib/admin/test_options.yml
Normal file
126
test-data/typecheck/contrib/admin/test_options.yml
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
# "Happy path" test for model admin, trying to cover as many valid
|
||||||
|
# configurations as possible.
|
||||||
|
- case: test_full_admin
|
||||||
|
main: |
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.forms import Form, Textarea
|
||||||
|
from django.db import models
|
||||||
|
from django.core.paginator import Paginator
|
||||||
|
from django.contrib.admin.sites import AdminSite
|
||||||
|
from django.db.models.options import Options
|
||||||
|
from django.http.request import HttpRequest
|
||||||
|
from django.db.models.query import QuerySet
|
||||||
|
|
||||||
|
def an_action(modeladmin: admin.ModelAdmin, request: HttpRequest, queryset: QuerySet) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class A(admin.ModelAdmin):
|
||||||
|
# BaseModelAdmin
|
||||||
|
autocomplete_fields = ("strs",)
|
||||||
|
raw_id_fields = ["strs"]
|
||||||
|
fields = (
|
||||||
|
"a field",
|
||||||
|
["a", "list of", "fields"],
|
||||||
|
)
|
||||||
|
exclude = ("a", "b")
|
||||||
|
fieldsets = [
|
||||||
|
(None, {"fields": ["a", "b"]}),
|
||||||
|
("group", {"fields": ("c",), "classes": ("a",), "description": "foo"}),
|
||||||
|
]
|
||||||
|
form = Form
|
||||||
|
filter_vertical = ("fields",)
|
||||||
|
filter_horizontal = ("plenty", "of", "fields")
|
||||||
|
radio_fields = {
|
||||||
|
"some_field": admin.VERTICAL,
|
||||||
|
"another_field": admin.HORIZONTAL,
|
||||||
|
}
|
||||||
|
prepopulated_fields = {"slug": ("title",)}
|
||||||
|
formfield_overrides = {models.TextField: {"widget": Textarea}}
|
||||||
|
readonly_fields = ("date_modified",)
|
||||||
|
ordering = ("-pk", "date_modified")
|
||||||
|
sortable_by = ["pk"]
|
||||||
|
view_on_site = True
|
||||||
|
show_full_result_count = False
|
||||||
|
|
||||||
|
# ModelAdmin
|
||||||
|
list_display = ("pk",)
|
||||||
|
list_display_links = ("str",)
|
||||||
|
list_filter = ("str", admin.SimpleListFilter, ("str", admin.SimpleListFilter))
|
||||||
|
list_select_related = True
|
||||||
|
list_per_page = 1
|
||||||
|
list_max_show_all = 2
|
||||||
|
list_editable = ("a", "b")
|
||||||
|
search_fields = ("c", "d")
|
||||||
|
date_hirearchy = "f"
|
||||||
|
save_as = False
|
||||||
|
save_as_continue = True
|
||||||
|
save_on_top = False
|
||||||
|
paginator = Paginator
|
||||||
|
presserve_filters = False
|
||||||
|
inlines = (admin.TabularInline, admin.StackedInline)
|
||||||
|
add_form_template = "template"
|
||||||
|
change_form_template = "template"
|
||||||
|
change_list_template = "template"
|
||||||
|
delete_confirmation_template = "template"
|
||||||
|
delete_selected_confirmation_template = "template"
|
||||||
|
object_history_template = "template"
|
||||||
|
popup_response_template = "template"
|
||||||
|
actions = (an_action,)
|
||||||
|
actions_on_top = True
|
||||||
|
actions_on_bottom = False
|
||||||
|
actions_selection_counter = True
|
||||||
|
admin_site = AdminSite()
|
||||||
|
# This test is here to make sure we're not running into a mypy issue which is
|
||||||
|
# worked around using a somewhat complicated _ListOrTuple union type. Once the
|
||||||
|
# issue is solved upstream this test should pass even with the workaround
|
||||||
|
# replaced by a simpler Sequence type.
|
||||||
|
# https://github.com/python/mypy/issues/8921
|
||||||
|
- case: test_fieldset_workaround_regression
|
||||||
|
main: |
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
class A(admin.ModelAdmin):
|
||||||
|
fieldsets = (
|
||||||
|
(None, {
|
||||||
|
'fields': ('name',),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
- case: errors_on_omitting_fields_from_fieldset_opts
|
||||||
|
main: |
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
class A(admin.ModelAdmin):
|
||||||
|
fieldsets = [ # type: ignore
|
||||||
|
(None, {}), # E: Key 'fields' missing for TypedDict "_FieldOpts"
|
||||||
|
]
|
||||||
|
- case: errors_on_invalid_radio_fields
|
||||||
|
main: |
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
class A(admin.ModelAdmin):
|
||||||
|
radio_fields = {"some_field": 0} # E: Dict entry 0 has incompatible type "str": "Literal[0]"; expected "str": "Union[Literal[1], Literal[2]]"
|
||||||
|
|
||||||
|
class B(admin.ModelAdmin):
|
||||||
|
radio_fields = {1: admin.VERTICAL} # E: Dict entry 0 has incompatible type "int": "Literal[2]"; expected "str": "Union[Literal[1], Literal[2]]"
|
||||||
|
- case: errors_for_invalid_formfield_overrides
|
||||||
|
main: |
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.forms import Textarea
|
||||||
|
|
||||||
|
class A(admin.ModelAdmin):
|
||||||
|
formfield_overrides = {
|
||||||
|
"not a field": { # E: Dict entry 0 has incompatible type "str": "Dict[str, Any]"; expected "Type[Field[Any, Any]]": "Mapping[str, Any]"
|
||||||
|
"widget": Textarea
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- case: errors_for_invalid_action_signature
|
||||||
|
main: |
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.http.request import HttpRequest
|
||||||
|
from django.db.models.query import QuerySet
|
||||||
|
|
||||||
|
def an_action(modeladmin: None) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class A(admin.ModelAdmin):
|
||||||
|
actions = [an_action] # E: List item 0 has incompatible type "Callable[[None], None]"; expected "Callable[[ModelAdmin, HttpRequest, QuerySet[Any]], None]"
|
||||||
@@ -10,6 +10,12 @@
|
|||||||
reveal_type(User().is_active) # N: Revealed type is 'builtins.bool*'
|
reveal_type(User().is_active) # N: Revealed type is 'builtins.bool*'
|
||||||
reveal_type(User().date_joined) # N: Revealed type is 'datetime.datetime*'
|
reveal_type(User().date_joined) # N: Revealed type is 'datetime.datetime*'
|
||||||
reveal_type(User().last_login) # N: Revealed type is 'Union[datetime.datetime, None]'
|
reveal_type(User().last_login) # N: Revealed type is 'Union[datetime.datetime, None]'
|
||||||
|
reveal_type(User().is_authenticated) # N: Revealed type is 'Literal[True]'
|
||||||
|
reveal_type(User().is_anonymous) # N: Revealed type is 'Literal[False]'
|
||||||
|
|
||||||
|
from django.contrib.auth.models import AnonymousUser
|
||||||
|
reveal_type(AnonymousUser().is_authenticated) # N: Revealed type is 'Literal[False]'
|
||||||
|
reveal_type(AnonymousUser().is_anonymous) # N: Revealed type is 'Literal[True]'
|
||||||
|
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
reveal_type(Permission().name) # N: Revealed type is 'builtins.str*'
|
reveal_type(Permission().name) # N: Revealed type is 'builtins.str*'
|
||||||
|
|||||||
14
test-data/typecheck/models/test_state.yml
Normal file
14
test-data/typecheck/models/test_state.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
- case: state_attribute_has_a_type_of_model_state
|
||||||
|
main: |
|
||||||
|
from myapp.models import MyUser
|
||||||
|
user = MyUser(pk=1)
|
||||||
|
reveal_type(user._state) # N: Revealed type is 'django.db.models.base.ModelState'
|
||||||
|
installed_apps:
|
||||||
|
- myapp
|
||||||
|
files:
|
||||||
|
- path: myapp/__init__.py
|
||||||
|
- path: myapp/models.py
|
||||||
|
content: |
|
||||||
|
from django.db import models
|
||||||
|
class MyUser(models.Model):
|
||||||
|
pass
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
disable_cache: true
|
disable_cache: true
|
||||||
main: |
|
main: |
|
||||||
from django.http.request import HttpRequest
|
from django.http.request import HttpRequest
|
||||||
reveal_type(HttpRequest().user) # N: Revealed type is 'myapp.models.MyUser'
|
reveal_type(HttpRequest().user) # N: Revealed type is 'Union[myapp.models.MyUser, django.contrib.auth.models.AnonymousUser]'
|
||||||
# check that other fields work ok
|
# check that other fields work ok
|
||||||
reveal_type(HttpRequest().method) # N: Revealed type is 'Union[builtins.str, None]'
|
reveal_type(HttpRequest().method) # N: Revealed type is 'Union[builtins.str, None]'
|
||||||
custom_settings: |
|
custom_settings: |
|
||||||
INSTALLED_APPS = ('django.contrib.contenttypes', 'myapp')
|
INSTALLED_APPS = ('django.contrib.contenttypes', 'django.contrib.auth', 'myapp')
|
||||||
AUTH_USER_MODEL='myapp.MyUser'
|
AUTH_USER_MODEL='myapp.MyUser'
|
||||||
files:
|
files:
|
||||||
- path: myapp/__init__.py
|
- path: myapp/__init__.py
|
||||||
@@ -15,3 +15,15 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
class MyUser(models.Model):
|
class MyUser(models.Model):
|
||||||
pass
|
pass
|
||||||
|
- case: request_object_user_can_be_descriminated
|
||||||
|
disable_cache: true
|
||||||
|
main: |
|
||||||
|
from django.http.request import HttpRequest
|
||||||
|
request = HttpRequest()
|
||||||
|
reveal_type(request.user) # N: Revealed type is 'Union[django.contrib.auth.models.User, django.contrib.auth.models.AnonymousUser]'
|
||||||
|
if not request.user.is_anonymous:
|
||||||
|
reveal_type(request.user) # N: Revealed type is 'django.contrib.auth.models.User'
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
reveal_type(request.user) # N: Revealed type is 'django.contrib.auth.models.User'
|
||||||
|
custom_settings: |
|
||||||
|
INSTALLED_APPS = ('django.contrib.contenttypes', 'django.contrib.auth')
|
||||||
|
|||||||
@@ -36,3 +36,24 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
class MyUser(models.Model):
|
class MyUser(models.Model):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
- case: check_render_function_arguments_annotations
|
||||||
|
main: |
|
||||||
|
from typing import Any
|
||||||
|
from typing_extensions import TypedDict
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.http.request import HttpRequest
|
||||||
|
|
||||||
|
TestContext = TypedDict("TestContext", {"user": Any})
|
||||||
|
test_context: TestContext = {"user": "test"}
|
||||||
|
reveal_type(test_context) # N: Revealed type is 'TypedDict('main.TestContext', {'user': Any})'
|
||||||
|
reveal_type(render(HttpRequest(), '', test_context)) # N: Revealed type is 'django.http.response.HttpResponse'
|
||||||
|
|
||||||
|
- case: check_redirect_return_annotation
|
||||||
|
main: |
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
reveal_type(redirect(to = '', permanent = True)) # N: Revealed type is 'django.http.response.HttpResponsePermanentRedirect'
|
||||||
|
reveal_type(redirect(to = '', permanent = False)) # N: Revealed type is 'django.http.response.HttpResponseRedirect'
|
||||||
|
|
||||||
|
var = True
|
||||||
|
reveal_type(redirect(to = '', permanent = var)) # N: Revealed type is 'Union[django.http.response.HttpResponseRedirect, django.http.response.HttpResponsePermanentRedirect]'
|
||||||
|
|||||||
Reference in New Issue
Block a user