mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-12 06:51:53 +08:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ea25f3e56 | ||
|
|
dacf88c692 | ||
|
|
3d14d07e4e | ||
|
|
6e6d1645d3 | ||
|
|
2bd018951b | ||
|
|
14ea848dd7 | ||
|
|
2d3b5492f0 | ||
|
|
194258ab8e | ||
|
|
116aa2c539 | ||
|
|
67c99434e5 | ||
|
|
5d8cdbcf29 | ||
|
|
78810f55b6 | ||
|
|
36662896bc | ||
|
|
e54dbb79c9 | ||
|
|
41f283552a | ||
|
|
ab73d53ae5 | ||
|
|
d24be4b35f | ||
|
|
9d60b472df | ||
|
|
632e063e22 | ||
|
|
66224416b5 |
@@ -7,6 +7,10 @@
|
|||||||
|
|
||||||
This package contains type stubs and mypy plugin to provide more precise static types and type inference for Django framework. Django uses some Python "magic" that makes having precise types for some code patterns problematic. This is why we need to accompany the stubs with mypy plugins. The final goal is to be able to get precise types for most common patterns.
|
This package contains type stubs and mypy plugin to provide more precise static types and type inference for Django framework. Django uses some Python "magic" that makes having precise types for some code patterns problematic. This is why we need to accompany the stubs with mypy plugins. The final goal is to be able to get precise types for most common patterns.
|
||||||
|
|
||||||
|
Supports Python 3.6/3.7, and Django 2.1.x series.
|
||||||
|
|
||||||
|
Could be run on earlier versions of Django, but expect some missing imports warnings.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ by the DJANGO_SETTINGS_MODULE environment variable.
|
|||||||
|
|
||||||
# This is defined here as a do-nothing function because we can't import
|
# This is defined here as a do-nothing function because we can't import
|
||||||
# django.utils.translation -- that module depends on the settings.
|
# django.utils.translation -- that module depends on the settings.
|
||||||
from typing import Any, Dict, List, Optional, Pattern, Tuple, Protocol, Union, Callable, TYPE_CHECKING
|
from typing import Any, Dict, List, Optional, Pattern, Tuple, Protocol, Union, Callable, TYPE_CHECKING, Sequence
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# CORE #
|
# CORE #
|
||||||
@@ -377,7 +377,7 @@ CACHE_MIDDLEWARE_ALIAS = "default"
|
|||||||
|
|
||||||
AUTH_USER_MODEL: str = ...
|
AUTH_USER_MODEL: str = ...
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS: List[str] = ...
|
AUTHENTICATION_BACKENDS: Sequence[str] = ...
|
||||||
|
|
||||||
LOGIN_URL = "/accounts/login/"
|
LOGIN_URL = "/accounts/login/"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from typing import Any, Callable, List, Optional
|
from typing import Any, Callable, List, Optional
|
||||||
|
|
||||||
from django.core.handlers.wsgi import WSGIRequest
|
from django import http
|
||||||
from django.http.response import HttpResponse, HttpResponseRedirect
|
from django.http.response import HttpResponse, HttpResponseRedirect
|
||||||
|
|
||||||
class AccessMixin:
|
class AccessMixin:
|
||||||
@@ -14,15 +14,15 @@ class AccessMixin:
|
|||||||
def handle_no_permission(self) -> HttpResponseRedirect: ...
|
def handle_no_permission(self) -> HttpResponseRedirect: ...
|
||||||
|
|
||||||
class LoginRequiredMixin(AccessMixin):
|
class LoginRequiredMixin(AccessMixin):
|
||||||
def dispatch(self, request: WSGIRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
|
def dispatch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
|
||||||
|
|
||||||
class PermissionRequiredMixin(AccessMixin):
|
class PermissionRequiredMixin(AccessMixin):
|
||||||
permission_required: Any = ...
|
permission_required: Any = ...
|
||||||
def get_permission_required(self) -> List[str]: ...
|
def get_permission_required(self) -> List[str]: ...
|
||||||
def has_permission(self) -> bool: ...
|
def has_permission(self) -> bool: ...
|
||||||
def dispatch(self, request: WSGIRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
|
def dispatch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
|
||||||
|
|
||||||
class UserPassesTestMixin(AccessMixin):
|
class UserPassesTestMixin(AccessMixin):
|
||||||
def test_func(self) -> None: ...
|
def test_func(self) -> None: ...
|
||||||
def get_test_func(self) -> Callable: ...
|
def get_test_func(self) -> Callable: ...
|
||||||
def dispatch(self, request: WSGIRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
|
def dispatch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
from typing import Any, Dict, Iterator, List, Optional, Tuple, Type, Union
|
from typing import Any, Dict, Iterator, List, Mapping, Optional, Tuple, Union
|
||||||
|
|
||||||
from django.db.models.base import Model
|
|
||||||
from django.forms.utils import ErrorDict
|
from django.forms.utils import ErrorDict
|
||||||
|
|
||||||
class FieldDoesNotExist(Exception): ...
|
class FieldDoesNotExist(Exception): ...
|
||||||
@@ -31,20 +30,13 @@ class ValidationError(Exception):
|
|||||||
message: Any = ...
|
message: Any = ...
|
||||||
code: Any = ...
|
code: Any = ...
|
||||||
params: Any = ...
|
params: Any = ...
|
||||||
def __init__(
|
def __init__(self, message: Any, code: Optional[str] = ..., params: Optional[Mapping[str, Any]] = ...) -> None: ...
|
||||||
self,
|
|
||||||
message: Any,
|
|
||||||
code: Optional[str] = ...,
|
|
||||||
params: Optional[
|
|
||||||
Union[Dict[str, Union[Tuple[str], Type[Model], Model, str]], Dict[str, Union[int, str]]]
|
|
||||||
] = ...,
|
|
||||||
) -> None: ...
|
|
||||||
@property
|
@property
|
||||||
def message_dict(self) -> Dict[str, List[str]]: ...
|
def message_dict(self) -> Dict[str, List[str]]: ...
|
||||||
@property
|
@property
|
||||||
def messages(self) -> List[str]: ...
|
def messages(self) -> List[str]: ...
|
||||||
def update_error_dict(
|
def update_error_dict(
|
||||||
self, error_dict: Union[Dict[str, List[ValidationError]], ErrorDict]
|
self, error_dict: Mapping[str, Any]
|
||||||
) -> Union[Dict[str, List[ValidationError]], ErrorDict]: ...
|
) -> Union[Dict[str, List[ValidationError]], ErrorDict]: ...
|
||||||
def __iter__(self) -> Iterator[Union[Tuple[str, List[str]], str]]: ...
|
def __iter__(self) -> Iterator[Union[Tuple[str, List[str]], str]]: ...
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ class InMemoryUploadedFile(UploadedFile):
|
|||||||
charset: Optional[str],
|
charset: Optional[str],
|
||||||
content_type_extra: Dict[str, str] = ...,
|
content_type_extra: Dict[str, str] = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
def chunks(self, chunk_size: int = None) -> Iterator[bytes]: ...
|
def chunks(self, chunk_size: Optional[int] = ...) -> Iterator[bytes]: ...
|
||||||
def multiple_chunks(self, chunk_size: int = None) -> bool: ...
|
def multiple_chunks(self, chunk_size: Optional[int] = ...) -> bool: ...
|
||||||
|
|
||||||
class SimpleUploadedFile(InMemoryUploadedFile):
|
class SimpleUploadedFile(InMemoryUploadedFile):
|
||||||
def __init__(self, name: str, content: bytes, content_type: str = "") -> None: ...
|
def __init__(self, name: str, content: Optional[Union[bytes, str]], content_type: str = ...) -> None: ...
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls: Any, file_dict: Dict[str, Union[str, bytes]]) -> None: ...
|
def from_dict(cls: Any, file_dict: Dict[str, Union[str, bytes]]) -> None: ...
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ from django.core.exceptions import FieldDoesNotExist as FieldDoesNotExist
|
|||||||
from django.db.models.expressions import Combinable
|
from django.db.models.expressions import Combinable
|
||||||
from django.db.models.query_utils import RegisterLookupMixin
|
from django.db.models.query_utils import RegisterLookupMixin
|
||||||
from django.forms import Field as FormField, Widget
|
from django.forms import Field as FormField, Widget
|
||||||
from typing_extensions import Literal
|
|
||||||
|
|
||||||
from .mixins import NOT_PROVIDED as NOT_PROVIDED
|
from .mixins import NOT_PROVIDED as NOT_PROVIDED
|
||||||
|
|
||||||
@@ -72,7 +71,7 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
|
|||||||
def to_python(self, value: Any) -> Any: ...
|
def to_python(self, value: Any) -> Any: ...
|
||||||
|
|
||||||
class IntegerField(Field[_ST, _GT]):
|
class IntegerField(Field[_ST, _GT]):
|
||||||
_pyi_private_set_type: Union[int, Combinable, Literal[""]]
|
_pyi_private_set_type: Union[float, int, str, Combinable]
|
||||||
_pyi_private_get_type: int
|
_pyi_private_get_type: int
|
||||||
|
|
||||||
class PositiveIntegerRelDbTypeMixin:
|
class PositiveIntegerRelDbTypeMixin:
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
from contextlib import ContextDecorator
|
from typing import Any, Callable, Optional, overload, TypeVar
|
||||||
from typing import Any, Callable, Optional, Union, Iterator, overload, ContextManager
|
|
||||||
|
|
||||||
from django.db import ProgrammingError
|
from django.db import ProgrammingError
|
||||||
|
|
||||||
@@ -18,19 +17,23 @@ def get_rollback(using: None = ...) -> bool: ...
|
|||||||
def set_rollback(rollback: bool, using: Optional[str] = ...) -> None: ...
|
def set_rollback(rollback: bool, using: Optional[str] = ...) -> None: ...
|
||||||
def on_commit(func: Callable, using: None = ...) -> None: ...
|
def on_commit(func: Callable, using: None = ...) -> None: ...
|
||||||
|
|
||||||
class Atomic(ContextDecorator):
|
_C = TypeVar("_C", bound=Callable) # Any callable
|
||||||
|
|
||||||
|
# Don't inherit from ContextDecorator, so we can provide a more specific signature for __call__
|
||||||
|
class Atomic:
|
||||||
using: Optional[str] = ...
|
using: Optional[str] = ...
|
||||||
savepoint: bool = ...
|
savepoint: bool = ...
|
||||||
def __init__(self, using: Optional[str], savepoint: bool) -> None: ...
|
def __init__(self, using: Optional[str], savepoint: bool) -> None: ...
|
||||||
|
# When decorating, return the decorated function as-is, rather than clobbering it as ContextDecorator does.
|
||||||
|
def __call__(self, func: _C) -> _C: ...
|
||||||
def __enter__(self) -> None: ...
|
def __enter__(self) -> None: ...
|
||||||
def __exit__(self, exc_type: None, exc_value: None, traceback: None) -> None: ...
|
def __exit__(self, exc_type: None, exc_value: None, traceback: None) -> None: ...
|
||||||
|
|
||||||
|
# Bare decorator
|
||||||
@overload
|
@overload
|
||||||
def atomic() -> Atomic: ...
|
def atomic(using: _C) -> _C: ...
|
||||||
|
|
||||||
|
# Decorator or context-manager with parameters
|
||||||
@overload
|
@overload
|
||||||
def atomic(using: Optional[str] = ...,) -> ContextManager[Atomic]: ...
|
def atomic(using: Optional[str] = None, savepoint: bool = True) -> Atomic: ...
|
||||||
@overload
|
|
||||||
def atomic(using: Callable = ...) -> Callable: ...
|
|
||||||
@overload
|
|
||||||
def atomic(using: Optional[str] = ..., savepoint: bool = ...) -> ContextManager[Atomic]: ...
|
|
||||||
def non_atomic_requests(using: Callable = ...) -> Callable: ...
|
def non_atomic_requests(using: Callable = ...) -> Callable: ...
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
import decimal
|
from datetime import datetime, timedelta
|
||||||
from datetime import date, datetime, time, timedelta
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from typing import Any, Callable, Dict, List, Optional, Tuple, Union, Type
|
from typing import Any, Callable, List, Optional, Pattern, Sequence, Type, Union
|
||||||
from uuid import UUID
|
|
||||||
|
|
||||||
from django.core.files.base import File
|
|
||||||
from django.core.validators import BaseValidator
|
from django.core.validators import BaseValidator
|
||||||
from django.db.models.fields.files import FieldFile
|
|
||||||
from django.forms.boundfield import BoundField
|
from django.forms.boundfield import BoundField
|
||||||
from django.forms.forms import BaseForm
|
from django.forms.forms import BaseForm
|
||||||
from django.forms.widgets import Widget
|
from django.forms.widgets import Widget
|
||||||
@@ -31,16 +27,16 @@ class Field:
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
required: bool = ...,
|
required: bool = ...,
|
||||||
widget: Optional[Any] = ...,
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
label: Optional[Any] = ...,
|
label: Optional[Any] = ...,
|
||||||
initial: Optional[Any] = ...,
|
initial: Optional[Any] = ...,
|
||||||
help_text: str = ...,
|
help_text: str = ...,
|
||||||
error_messages: Optional[Any] = ...,
|
error_messages: Optional[Any] = ...,
|
||||||
show_hidden_initial: bool = ...,
|
show_hidden_initial: bool = ...,
|
||||||
validators: Any = ...,
|
validators: Sequence[Any] = ...,
|
||||||
localize: bool = ...,
|
localize: bool = ...,
|
||||||
disabled: bool = ...,
|
disabled: bool = ...,
|
||||||
label_suffix: Optional[Any] = ...
|
label_suffix: Optional[Any] = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
def prepare_value(self, value: Any) -> Any: ...
|
def prepare_value(self, value: Any) -> Any: ...
|
||||||
def to_python(self, value: Optional[Any]) -> Optional[Any]: ...
|
def to_python(self, value: Optional[Any]) -> Optional[Any]: ...
|
||||||
@@ -49,60 +45,60 @@ class Field:
|
|||||||
def clean(self, value: Any) -> Any: ...
|
def clean(self, value: Any) -> Any: ...
|
||||||
def bound_data(self, data: Any, initial: Any) -> Any: ...
|
def bound_data(self, data: Any, initial: Any) -> Any: ...
|
||||||
def widget_attrs(self, widget: Widget) -> Any: ...
|
def widget_attrs(self, widget: Widget) -> Any: ...
|
||||||
def has_changed(self, initial: Any, data: Optional[str]) -> bool: ...
|
def has_changed(self, initial: Any, data: Any) -> bool: ...
|
||||||
def get_bound_field(self, form: BaseForm, field_name: str) -> BoundField: ...
|
def get_bound_field(self, form: BaseForm, field_name: str) -> BoundField: ...
|
||||||
def __deepcopy__(self, memo: Dict[Any, Any]) -> Field: ...
|
|
||||||
|
|
||||||
class CharField(Field):
|
class CharField(Field):
|
||||||
disabled: bool
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
max_length: Optional[Union[int, str]] = ...
|
max_length: Optional[Union[int, str]] = ...
|
||||||
min_length: Optional[Union[int, str]] = ...
|
min_length: Optional[Union[int, str]] = ...
|
||||||
strip: bool = ...
|
strip: bool = ...
|
||||||
empty_value: Optional[str] = ...
|
empty_value: Optional[str] = ...
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
|
||||||
max_length: Optional[Any] = ...,
|
max_length: Optional[Any] = ...,
|
||||||
min_length: Optional[Any] = ...,
|
min_length: Optional[Any] = ...,
|
||||||
strip: bool = ...,
|
strip: bool = ...,
|
||||||
empty_value: str = ...,
|
empty_value: Optional[str] = ...,
|
||||||
**kwargs: Any
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|
||||||
class IntegerField(Field):
|
class IntegerField(Field):
|
||||||
disabled: bool
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
max_value: Optional[Any]
|
max_value: Optional[Any]
|
||||||
min_value: Optional[Any]
|
min_value: Optional[Any]
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
re_decimal: Any = ...
|
re_decimal: Any = ...
|
||||||
def __init__(self, *, max_value: Optional[Any] = ..., min_value: Optional[Any] = ..., **kwargs: Any) -> None: ...
|
def __init__(
|
||||||
|
self,
|
||||||
|
max_value: Optional[Any] = ...,
|
||||||
|
min_value: Optional[Any] = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
|
|
||||||
class FloatField(IntegerField):
|
class FloatField(IntegerField):
|
||||||
disabled: bool
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
max_value: Optional[float]
|
|
||||||
min_value: Optional[float]
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
def validate(self, value: Optional[float]) -> None: ...
|
def validate(self, value: Optional[float]) -> None: ...
|
||||||
|
|
||||||
class DecimalField(IntegerField):
|
class DecimalField(IntegerField):
|
||||||
decimal_places: Optional[int]
|
decimal_places: Optional[int]
|
||||||
disabled: bool
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
max_digits: Optional[int]
|
max_digits: Optional[int]
|
||||||
max_value: Optional[Union[decimal.Decimal, int]]
|
|
||||||
min_value: Optional[Union[decimal.Decimal, int]]
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@@ -110,118 +106,95 @@ class DecimalField(IntegerField):
|
|||||||
min_value: Optional[Any] = ...,
|
min_value: Optional[Any] = ...,
|
||||||
max_digits: Optional[Any] = ...,
|
max_digits: Optional[Any] = ...,
|
||||||
decimal_places: Optional[Any] = ...,
|
decimal_places: Optional[Any] = ...,
|
||||||
**kwargs: Any
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
def validate(self, value: Optional[Decimal]) -> None: ...
|
def validate(self, value: Optional[Decimal]) -> None: ...
|
||||||
|
|
||||||
class BaseTemporalField(Field):
|
class BaseTemporalField(Field):
|
||||||
input_formats: Any = ...
|
input_formats: Any = ...
|
||||||
def __init__(self, *, input_formats: Optional[Any] = ..., **kwargs: Any) -> None: ...
|
def __init__(
|
||||||
def strptime(self, value: Any, format: Any) -> Any: ...
|
self,
|
||||||
|
input_formats: Optional[Any] = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
|
def strptime(self, value: Any, format: str) -> Any: ...
|
||||||
|
|
||||||
class DateField(BaseTemporalField):
|
class DateField(BaseTemporalField): ...
|
||||||
disabled: bool
|
class TimeField(BaseTemporalField): ...
|
||||||
error_messages: Dict[str, str]
|
class DateTimeField(BaseTemporalField): ...
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
input_formats: Any = ...
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
def strptime(self, value: str, format: str) -> date: ...
|
|
||||||
|
|
||||||
class TimeField(BaseTemporalField):
|
|
||||||
disabled: bool
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
input_formats: Any = ...
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
def strptime(self, value: str, format: str) -> time: ...
|
|
||||||
|
|
||||||
class DateTimeField(BaseTemporalField):
|
|
||||||
disabled: bool
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
input_formats: Any = ...
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
def prepare_value(self, value: Optional[datetime]) -> Optional[datetime]: ...
|
|
||||||
def strptime(self, value: str, format: str) -> datetime: ...
|
|
||||||
|
|
||||||
class DurationField(Field):
|
class DurationField(Field):
|
||||||
disabled: bool
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
def prepare_value(self, value: Optional[Union[timedelta, str]]) -> Optional[str]: ...
|
def prepare_value(self, value: Optional[Union[timedelta, str]]) -> Optional[str]: ...
|
||||||
|
|
||||||
class RegexField(CharField):
|
class RegexField(CharField):
|
||||||
disabled: bool
|
regex: str = ...
|
||||||
empty_value: str
|
def __init__(
|
||||||
error_messages: Dict[str, str]
|
self,
|
||||||
max_length: Optional[int]
|
regex: Union[str, Pattern],
|
||||||
min_length: Optional[int]
|
max_length: Optional[Any] = ...,
|
||||||
required: bool
|
min_length: Optional[Any] = ...,
|
||||||
show_hidden_initial: bool
|
strip: bool = ...,
|
||||||
strip: bool
|
empty_value: Optional[str] = ...,
|
||||||
def __init__(self, regex: str, **kwargs: Any) -> None: ...
|
required: bool = ...,
|
||||||
regex: Any = ...
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
|
|
||||||
class EmailField(CharField):
|
class EmailField(CharField): ...
|
||||||
disabled: bool
|
|
||||||
empty_value: Optional[str]
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
max_length: Optional[int]
|
|
||||||
min_length: Optional[int]
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
strip: bool
|
|
||||||
default_validators: Any = ...
|
|
||||||
def __init__(self, **kwargs: Any) -> None: ...
|
|
||||||
|
|
||||||
class FileField(Field):
|
class FileField(Field):
|
||||||
disabled: bool
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
max_length: Optional[int] = ...
|
max_length: Optional[int] = ...
|
||||||
allow_empty_file: bool = ...
|
allow_empty_file: bool = ...
|
||||||
def __init__(self, *, max_length: Optional[Any] = ..., allow_empty_file: bool = ..., **kwargs: Any) -> None: ...
|
def __init__(
|
||||||
def bound_data(self, data: Any, initial: Optional[FieldFile]) -> Optional[Union[File, str]]: ...
|
self,
|
||||||
|
max_length: Optional[Any] = ...,
|
||||||
|
allow_empty_file: bool = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
|
def clean(self, data: Any, initial: Optional[Any] = ...): ...
|
||||||
|
|
||||||
class ImageField(FileField):
|
class ImageField(FileField): ...
|
||||||
allow_empty_file: bool
|
class URLField(CharField): ...
|
||||||
disabled: bool
|
class BooleanField(Field): ...
|
||||||
max_length: Optional[int]
|
class NullBooleanField(BooleanField): ...
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
default_validators: Any = ...
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
|
|
||||||
class URLField(CharField):
|
|
||||||
disabled: bool
|
|
||||||
empty_value: Optional[str]
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
max_length: Optional[int]
|
|
||||||
min_length: Optional[int]
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
strip: bool
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
default_validators: Any = ...
|
|
||||||
def __init__(self, **kwargs: Any) -> None: ...
|
|
||||||
|
|
||||||
class BooleanField(Field):
|
|
||||||
disabled: bool
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
def validate(self, value: bool) -> None: ...
|
|
||||||
|
|
||||||
class NullBooleanField(BooleanField):
|
|
||||||
disabled: bool
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
def validate(self, value: Optional[bool]) -> None: ...
|
|
||||||
|
|
||||||
class CallableChoiceIterator:
|
class CallableChoiceIterator:
|
||||||
choices_func: Callable = ...
|
choices_func: Callable = ...
|
||||||
@@ -229,125 +202,191 @@ class CallableChoiceIterator:
|
|||||||
def __iter__(self) -> None: ...
|
def __iter__(self) -> None: ...
|
||||||
|
|
||||||
class ChoiceField(Field):
|
class ChoiceField(Field):
|
||||||
disabled: bool
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
choices: Any = ...
|
choices: Any = ...
|
||||||
def __init__(self, *, choices: Any = ..., **kwargs: Any) -> None: ...
|
def __init__(
|
||||||
def validate(self, value: Any) -> None: ...
|
self,
|
||||||
|
choices: Any = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
def valid_value(self, value: str) -> bool: ...
|
def valid_value(self, value: str) -> bool: ...
|
||||||
|
|
||||||
class TypedChoiceField(ChoiceField):
|
class TypedChoiceField(ChoiceField):
|
||||||
disabled: bool
|
coerce: Union[Callable, Type[Any]] = ...
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
coerce: Union[Callable, Type[Union[bool, float, str]]] = ...
|
|
||||||
empty_value: Optional[str] = ...
|
empty_value: Optional[str] = ...
|
||||||
def __init__(self, *, coerce: Any = ..., empty_value: str = ..., **kwargs: Any) -> None: ...
|
def __init__(
|
||||||
|
self,
|
||||||
|
coerce: Any = ...,
|
||||||
|
empty_value: Optional[str] = ...,
|
||||||
|
choices: Any = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
|
|
||||||
class MultipleChoiceField(ChoiceField):
|
class MultipleChoiceField(ChoiceField): ...
|
||||||
disabled: bool
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
hidden_widget: Any = ...
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
def validate(self, value: List[str]) -> None: ...
|
|
||||||
|
|
||||||
class TypedMultipleChoiceField(MultipleChoiceField):
|
class TypedMultipleChoiceField(MultipleChoiceField):
|
||||||
disabled: bool
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
coerce: Union[Callable, Type[float]] = ...
|
coerce: Union[Callable, Type[float]] = ...
|
||||||
empty_value: Optional[List[Any]] = ...
|
empty_value: Optional[List[Any]] = ...
|
||||||
def __init__(self, *, coerce: Any = ..., **kwargs: Any) -> None: ...
|
def __init__(
|
||||||
def validate(self, value: List[str]) -> None: ...
|
self,
|
||||||
|
coerce: Any = ...,
|
||||||
|
empty_value: Optional[str] = ...,
|
||||||
|
choices: Any = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
|
|
||||||
class ComboField(Field):
|
class ComboField(Field):
|
||||||
disabled: bool
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
fields: Any = ...
|
fields: Any = ...
|
||||||
def __init__(self, fields: List[CharField], **kwargs: Any) -> None: ...
|
def __init__(
|
||||||
|
self,
|
||||||
|
fields: Sequence[Field],
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
|
|
||||||
class MultiValueField(Field):
|
class MultiValueField(Field):
|
||||||
disabled: bool
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
require_all_fields: bool = ...
|
require_all_fields: bool = ...
|
||||||
fields: Any = ...
|
fields: Any = ...
|
||||||
def __init__(self, fields: Tuple[Field, Field], *, require_all_fields: bool = ..., **kwargs: Any) -> None: ...
|
def __init__(
|
||||||
def validate(self, value: Union[datetime, str]) -> None: ...
|
self,
|
||||||
|
fields: Sequence[Field],
|
||||||
|
require_all_fields: bool = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
def compress(self, data_list: Any) -> Any: ...
|
def compress(self, data_list: Any) -> Any: ...
|
||||||
|
|
||||||
class FilePathField(ChoiceField):
|
class FilePathField(ChoiceField):
|
||||||
allow_files: bool
|
allow_files: bool
|
||||||
allow_folders: bool
|
allow_folders: bool
|
||||||
disabled: bool
|
|
||||||
match: Optional[str]
|
match: Optional[str]
|
||||||
path: str
|
path: str
|
||||||
recursive: bool
|
recursive: bool
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
choices: Any = ...
|
|
||||||
match_re: Any = ...
|
match_re: Any = ...
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
path: str,
|
path: str,
|
||||||
*,
|
|
||||||
match: Optional[Any] = ...,
|
match: Optional[Any] = ...,
|
||||||
recursive: bool = ...,
|
recursive: bool = ...,
|
||||||
allow_files: bool = ...,
|
allow_files: bool = ...,
|
||||||
allow_folders: bool = ...,
|
allow_folders: bool = ...,
|
||||||
**kwargs: Any
|
choices: Any = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|
||||||
class SplitDateTimeField(MultiValueField):
|
class SplitDateTimeField(MultiValueField):
|
||||||
disabled: bool
|
|
||||||
require_all_fields: bool
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
hidden_widget: Any = ...
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, *, input_date_formats: Optional[Any] = ..., input_time_formats: Optional[Any] = ..., **kwargs: Any
|
self,
|
||||||
|
input_date_formats: Optional[Any] = ...,
|
||||||
|
input_time_formats: Optional[Any] = ...,
|
||||||
|
fields: Sequence[Field] = ...,
|
||||||
|
require_all_fields: bool = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
def compress(self, data_list: List[Optional[datetime]]) -> Optional[datetime]: ...
|
def compress(self, data_list: List[Optional[datetime]]) -> Optional[datetime]: ...
|
||||||
|
|
||||||
class GenericIPAddressField(CharField):
|
class GenericIPAddressField(CharField):
|
||||||
disabled: bool
|
|
||||||
empty_value: str
|
|
||||||
error_messages: Dict[str, str]
|
|
||||||
max_length: None
|
|
||||||
min_length: None
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
strip: bool
|
|
||||||
unpack_ipv4: bool = ...
|
unpack_ipv4: bool = ...
|
||||||
default_validators: List[Callable] = ...
|
def __init__(
|
||||||
def __init__(self, *, protocol: str = ..., unpack_ipv4: bool = ..., **kwargs: Any) -> None: ...
|
self,
|
||||||
|
protocol: str = ...,
|
||||||
|
unpack_ipv4: bool = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
|
|
||||||
class SlugField(CharField):
|
class SlugField(CharField):
|
||||||
disabled: bool
|
|
||||||
empty_value: str
|
|
||||||
max_length: Optional[int]
|
|
||||||
min_length: None
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
strip: bool
|
|
||||||
allow_unicode: bool = ...
|
allow_unicode: bool = ...
|
||||||
def __init__(self, *, allow_unicode: bool = ..., **kwargs: Any) -> None: ...
|
def __init__(
|
||||||
|
self,
|
||||||
|
allow_unicode: bool = ...,
|
||||||
|
required: bool = ...,
|
||||||
|
widget: Optional[Union[Widget, Type[Widget]]] = ...,
|
||||||
|
label: Optional[Any] = ...,
|
||||||
|
initial: Optional[Any] = ...,
|
||||||
|
help_text: str = ...,
|
||||||
|
error_messages: Optional[Any] = ...,
|
||||||
|
show_hidden_initial: bool = ...,
|
||||||
|
validators: Sequence[Any] = ...,
|
||||||
|
localize: bool = ...,
|
||||||
|
disabled: bool = ...,
|
||||||
|
label_suffix: Optional[Any] = ...,
|
||||||
|
) -> None: ...
|
||||||
|
|
||||||
class UUIDField(CharField):
|
class UUIDField(CharField): ...
|
||||||
disabled: bool
|
|
||||||
empty_value: str
|
|
||||||
max_length: None
|
|
||||||
min_length: None
|
|
||||||
required: bool
|
|
||||||
show_hidden_initial: bool
|
|
||||||
strip: bool
|
|
||||||
default_error_messages: Any = ...
|
|
||||||
def prepare_value(self, value: UUID) -> str: ...
|
|
||||||
|
|||||||
@@ -1,48 +1,45 @@
|
|||||||
from collections import OrderedDict
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any, Dict, Iterator, List, Mapping, Optional, Tuple, 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.base import File
|
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
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.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.safestring import SafeText
|
from django.utils.safestring import SafeText
|
||||||
|
|
||||||
class DeclarativeFieldsMetaclass(MediaDefiningClass):
|
class DeclarativeFieldsMetaclass(MediaDefiningClass):
|
||||||
def __new__(
|
def __new__(mcs, name: str, bases: Sequence[Type[BaseForm]], attrs: Dict[str, Any]) -> Type[BaseForm]: ...
|
||||||
mcs: Type[DeclarativeFieldsMetaclass], name: str, bases: Tuple[Type[BaseForm]], attrs: OrderedDict
|
|
||||||
) -> Type[BaseForm]: ...
|
|
||||||
|
|
||||||
class BaseForm:
|
class BaseForm:
|
||||||
default_renderer: Any = ...
|
default_renderer: Any = ...
|
||||||
field_order: Any = ...
|
field_order: Any = ...
|
||||||
prefix: Any = ...
|
|
||||||
use_required_attribute: bool = ...
|
use_required_attribute: bool = ...
|
||||||
is_bound: Any = ...
|
is_bound: bool = ...
|
||||||
data: Any = ...
|
data: Dict[str, Any] = ...
|
||||||
files: Any = ...
|
files: Optional[Dict[str, Any]] = ...
|
||||||
auto_id: Any = ...
|
auto_id: Any = ...
|
||||||
initial: Any = ...
|
initial: Dict[str, Any] = ...
|
||||||
error_class: Any = ...
|
error_class: Type[ErrorList] = ...
|
||||||
label_suffix: Any = ...
|
prefix: str = ...
|
||||||
empty_permitted: Any = ...
|
label_suffix: str = ...
|
||||||
fields: Any = ...
|
empty_permitted: bool = ...
|
||||||
renderer: Any = ...
|
fields: Dict[str, Any] = ...
|
||||||
|
renderer: BaseRenderer = ...
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
data: Optional[Mapping[str, Any]] = ...,
|
data: Optional[Mapping[str, Any]] = ...,
|
||||||
files: Optional[Mapping[str, File]] = ...,
|
files: Optional[Mapping[str, Any]] = ...,
|
||||||
auto_id: Optional[Union[bool, str]] = ...,
|
auto_id: Optional[Union[bool, str]] = ...,
|
||||||
prefix: Optional[str] = ...,
|
prefix: Optional[str] = ...,
|
||||||
initial: Optional[Mapping[str, Any]] = ...,
|
initial: Optional[Mapping[str, Any]] = ...,
|
||||||
error_class: Type[ErrorList] = ...,
|
error_class: Type[ErrorList] = ...,
|
||||||
label_suffix: None = ...,
|
label_suffix: Optional[str] = ...,
|
||||||
empty_permitted: bool = ...,
|
empty_permitted: bool = ...,
|
||||||
field_order: None = ...,
|
field_order: Optional[Any] = ...,
|
||||||
use_required_attribute: Optional[bool] = ...,
|
use_required_attribute: Optional[bool] = ...,
|
||||||
renderer: Any = ...,
|
renderer: Any = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
import collections
|
from typing import Any, Dict, Mapping, Optional, Sequence, Sized
|
||||||
from typing import Any, List, Optional, Union, Dict, Type
|
|
||||||
|
|
||||||
from django.forms.renderers import BaseRenderer
|
|
||||||
from django.forms.utils import ErrorList
|
|
||||||
|
|
||||||
from django.forms import Form
|
from django.forms import Form
|
||||||
|
|
||||||
@@ -17,21 +13,9 @@ DEFAULT_MIN_NUM: int = ...
|
|||||||
DEFAULT_MAX_NUM: int = ...
|
DEFAULT_MAX_NUM: int = ...
|
||||||
|
|
||||||
class ManagementForm(Form):
|
class ManagementForm(Form):
|
||||||
auto_id: Union[bool, str]
|
|
||||||
cleaned_data: Dict[str, Optional[int]]
|
cleaned_data: Dict[str, Optional[int]]
|
||||||
data: Dict[str, Union[List[int], int, str]]
|
|
||||||
empty_permitted: bool
|
|
||||||
error_class: Type[ErrorList]
|
|
||||||
fields: collections.OrderedDict
|
|
||||||
files: Dict[Any, Any]
|
|
||||||
initial: Dict[str, int]
|
|
||||||
is_bound: bool
|
|
||||||
label_suffix: str
|
|
||||||
prefix: str
|
|
||||||
renderer: BaseRenderer
|
|
||||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
|
|
||||||
|
|
||||||
class BaseFormSet:
|
class BaseFormSet(Sized, Mapping[str, Any]):
|
||||||
is_bound: Any = ...
|
is_bound: Any = ...
|
||||||
prefix: Any = ...
|
prefix: Any = ...
|
||||||
auto_id: Any = ...
|
auto_id: Any = ...
|
||||||
@@ -57,6 +41,7 @@ class BaseFormSet:
|
|||||||
def management_form(self): ...
|
def management_form(self): ...
|
||||||
def total_form_count(self): ...
|
def total_form_count(self): ...
|
||||||
def initial_form_count(self): ...
|
def initial_form_count(self): ...
|
||||||
|
@property
|
||||||
def forms(self): ...
|
def forms(self): ...
|
||||||
def get_form_kwargs(self, index: Any): ...
|
def get_form_kwargs(self, index: Any): ...
|
||||||
@property
|
@property
|
||||||
@@ -101,4 +86,4 @@ def formset_factory(
|
|||||||
min_num: Optional[Any] = ...,
|
min_num: Optional[Any] = ...,
|
||||||
validate_min: bool = ...,
|
validate_min: bool = ...,
|
||||||
): ...
|
): ...
|
||||||
def all_valid(formsets: List[Any]) -> bool: ...
|
def all_valid(formsets: Sequence[Any]) -> bool: ...
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple, Type, Union, Sequence
|
from typing import Any, Callable, Dict, Iterator, List, MutableMapping, Optional, Sequence, Tuple, Type, Union
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.base import File
|
||||||
|
from django.db import models
|
||||||
from django.db.models import ForeignKey
|
from django.db.models import ForeignKey
|
||||||
from django.db.models.base import Model
|
from django.db.models.base import Model
|
||||||
from django.db.models.manager import Manager
|
from django.db.models.manager import Manager
|
||||||
@@ -14,9 +15,8 @@ from django.forms.fields import CharField, ChoiceField, Field
|
|||||||
from django.forms.forms import BaseForm, DeclarativeFieldsMetaclass
|
from django.forms.forms import BaseForm, DeclarativeFieldsMetaclass
|
||||||
from django.forms.formsets import BaseFormSet
|
from django.forms.formsets import BaseFormSet
|
||||||
from django.forms.utils import ErrorList
|
from django.forms.utils import ErrorList
|
||||||
from django.forms.widgets import Input, Widget, Select
|
from django.forms.widgets import Input, Widget
|
||||||
from django.http.request import QueryDict
|
from typing_extensions import Literal
|
||||||
from django.utils.datastructures import MultiValueDict
|
|
||||||
|
|
||||||
ALL_FIELDS: str
|
ALL_FIELDS: str
|
||||||
|
|
||||||
@@ -57,21 +57,19 @@ class ModelFormOptions:
|
|||||||
def __init__(self, options: Optional[type] = ...) -> None: ...
|
def __init__(self, options: Optional[type] = ...) -> None: ...
|
||||||
|
|
||||||
class ModelFormMetaclass(DeclarativeFieldsMetaclass):
|
class ModelFormMetaclass(DeclarativeFieldsMetaclass):
|
||||||
def __new__(
|
def __new__(mcs, name: str, bases: Sequence[Type[ModelForm]], attrs: Dict[str, Any]) -> Type[ModelForm]: ...
|
||||||
mcs: Type[ModelFormMetaclass], name: str, bases: Tuple[Type[ModelForm]], attrs: OrderedDict
|
|
||||||
) -> Type[ModelForm]: ...
|
|
||||||
|
|
||||||
class BaseModelForm(BaseForm):
|
class BaseModelForm(BaseForm):
|
||||||
instance: Any = ...
|
instance: Any = ...
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
data: Optional[Union[Dict[str, Any], QueryDict]] = ...,
|
data: Optional[Dict[str, Any]] = ...,
|
||||||
files: Optional[Union[Dict[str, SimpleUploadedFile], MultiValueDict]] = ...,
|
files: Optional[Dict[str, File]] = ...,
|
||||||
auto_id: Union[bool, str] = ...,
|
auto_id: Union[bool, str] = ...,
|
||||||
prefix: None = ...,
|
prefix: Optional[str] = ...,
|
||||||
initial: Optional[Union[Dict[str, List[int]], Dict[str, int]]] = ...,
|
initial: Optional[Dict[str, Any]] = ...,
|
||||||
error_class: Type[ErrorList] = ...,
|
error_class: Type[ErrorList] = ...,
|
||||||
label_suffix: None = ...,
|
label_suffix: Optional[str] = ...,
|
||||||
empty_permitted: bool = ...,
|
empty_permitted: bool = ...,
|
||||||
instance: Optional[Model] = ...,
|
instance: Optional[Model] = ...,
|
||||||
use_required_attribute: None = ...,
|
use_required_attribute: None = ...,
|
||||||
@@ -87,16 +85,16 @@ class ModelForm(BaseModelForm): ...
|
|||||||
def modelform_factory(
|
def modelform_factory(
|
||||||
model: Type[Model],
|
model: Type[Model],
|
||||||
form: Type[ModelForm] = ...,
|
form: Type[ModelForm] = ...,
|
||||||
fields: Optional[Union[List[str], str]] = ...,
|
fields: Optional[Union[Sequence[str], Literal["__all__"]]] = ...,
|
||||||
exclude: None = ...,
|
exclude: Optional[Sequence[str]] = ...,
|
||||||
formfield_callback: Optional[str] = ...,
|
formfield_callback: Optional[Union[str, Callable[[models.Field], Field]]] = ...,
|
||||||
widgets: None = ...,
|
widgets: Optional[MutableMapping[str, Widget]] = ...,
|
||||||
localized_fields: None = ...,
|
localized_fields: Optional[Sequence[str]] = ...,
|
||||||
labels: None = ...,
|
labels: Optional[MutableMapping[str, str]] = ...,
|
||||||
help_texts: None = ...,
|
help_texts: Optional[MutableMapping[str, str]] = ...,
|
||||||
error_messages: None = ...,
|
error_messages: Optional[MutableMapping[str, Dict[str, Any]]] = ...,
|
||||||
field_classes: None = ...,
|
field_classes: Optional[MutableMapping[str, Type[Field]]] = ...,
|
||||||
) -> Any: ...
|
) -> Type[ModelForm]: ...
|
||||||
|
|
||||||
class BaseModelFormSet(BaseFormSet):
|
class BaseModelFormSet(BaseFormSet):
|
||||||
model: Any = ...
|
model: Any = ...
|
||||||
@@ -148,13 +146,13 @@ def modelformset_factory(
|
|||||||
exclude: Optional[Sequence[str]] = ...,
|
exclude: Optional[Sequence[str]] = ...,
|
||||||
widgets: Optional[Dict[str, Any]] = ...,
|
widgets: Optional[Dict[str, Any]] = ...,
|
||||||
validate_max: bool = ...,
|
validate_max: bool = ...,
|
||||||
localized_fields: None = ...,
|
localized_fields: Optional[Sequence[str]] = ...,
|
||||||
labels: Optional[Dict[str, str]] = ...,
|
labels: Optional[Dict[str, str]] = ...,
|
||||||
help_texts: Optional[Dict[str, str]] = ...,
|
help_texts: Optional[Dict[str, str]] = ...,
|
||||||
error_messages: Optional[Dict[str, Dict[str, str]]] = ...,
|
error_messages: Optional[Dict[str, Dict[str, str]]] = ...,
|
||||||
validate_min: bool = ...,
|
validate_min: bool = ...,
|
||||||
field_classes: Optional[Dict[str, Any]] = ...,
|
field_classes: Optional[Dict[str, Type[Field]]] = ...,
|
||||||
) -> Any: ...
|
) -> Type[BaseModelFormSet]: ...
|
||||||
|
|
||||||
class BaseInlineFormSet(BaseModelFormSet):
|
class BaseInlineFormSet(BaseModelFormSet):
|
||||||
instance: Any = ...
|
instance: Any = ...
|
||||||
@@ -192,14 +190,14 @@ def inlineformset_factory(
|
|||||||
formfield_callback: Optional[Callable] = ...,
|
formfield_callback: Optional[Callable] = ...,
|
||||||
widgets: Optional[Dict[str, Any]] = ...,
|
widgets: Optional[Dict[str, Any]] = ...,
|
||||||
validate_max: bool = ...,
|
validate_max: bool = ...,
|
||||||
localized_fields: None = ...,
|
localized_fields: Optional[Sequence[str]] = ...,
|
||||||
labels: Optional[Dict[str, str]] = ...,
|
labels: Optional[Dict[str, str]] = ...,
|
||||||
help_texts: Optional[Dict[str, str]] = ...,
|
help_texts: Optional[Dict[str, str]] = ...,
|
||||||
error_messages: Optional[Dict[str, Dict[str, str]]] = ...,
|
error_messages: Optional[Dict[str, Dict[str, str]]] = ...,
|
||||||
min_num: Optional[int] = ...,
|
min_num: Optional[int] = ...,
|
||||||
validate_min: bool = ...,
|
validate_min: bool = ...,
|
||||||
field_classes: Optional[Dict[str, Any]] = ...,
|
field_classes: Optional[Dict[str, Any]] = ...,
|
||||||
) -> Any: ...
|
) -> Type[BaseInlineFormSet]: ...
|
||||||
|
|
||||||
class InlineForeignKeyField(Field):
|
class InlineForeignKeyField(Field):
|
||||||
disabled: bool
|
disabled: bool
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ from django.core.exceptions import ValidationError
|
|||||||
from django.utils.safestring import SafeText
|
from django.utils.safestring import SafeText
|
||||||
|
|
||||||
def pretty_name(name: str) -> str: ...
|
def pretty_name(name: str) -> str: ...
|
||||||
def flatatt(attrs: Dict[str, Optional[str]]) -> SafeText: ...
|
def flatatt(attrs: Dict[str, Any]) -> SafeText: ...
|
||||||
|
|
||||||
class ErrorDict(dict):
|
class ErrorDict(dict):
|
||||||
def as_data(self) -> Dict[str, List[ValidationError]]: ...
|
def as_data(self) -> Dict[str, List[ValidationError]]: ...
|
||||||
def get_json_data(self, escape_html: bool = ...) -> Dict[str, List[Dict[str, str]]]: ...
|
def get_json_data(self, escape_html: bool = ...) -> Dict[str, Any]: ...
|
||||||
def as_json(self, escape_html: bool = ...) -> str: ...
|
def as_json(self, escape_html: bool = ...) -> str: ...
|
||||||
def as_ul(self) -> str: ...
|
def as_ul(self) -> str: ...
|
||||||
def as_text(self) -> str: ...
|
def as_text(self) -> str: ...
|
||||||
@@ -19,7 +19,9 @@ class ErrorList(UserList):
|
|||||||
data: List[Union[ValidationError, str]]
|
data: List[Union[ValidationError, str]]
|
||||||
error_class: str = ...
|
error_class: str = ...
|
||||||
def __init__(
|
def __init__(
|
||||||
self, initlist: Optional[Union[ErrorList, Sequence[str]]] = ..., error_class: Optional[str] = ...
|
self,
|
||||||
|
initlist: Optional[Union[ErrorList, Sequence[Union[str, Exception]]]] = ...,
|
||||||
|
error_class: Optional[str] = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
def as_data(self) -> List[ValidationError]: ...
|
def as_data(self) -> List[ValidationError]: ...
|
||||||
def get_json_data(self, escape_html: bool = ...) -> List[Dict[str, str]]: ...
|
def get_json_data(self, escape_html: bool = ...) -> List[Dict[str, str]]: ...
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
from datetime import time
|
from datetime import time
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import Any, Callable, Dict, Iterator, List, Optional, Set, Tuple, Type, Union, Iterable, Sequence
|
from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Sequence, Set, Tuple, Type, Union
|
||||||
|
|
||||||
from django.contrib.admin.options import BaseModelAdmin
|
|
||||||
from django.core.files.base import File
|
from django.core.files.base import File
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
|
||||||
from django.db.models.fields.files import FieldFile
|
from django.db.models.fields.files import FieldFile
|
||||||
from django.forms.forms import BaseForm
|
|
||||||
from django.forms.renderers import EngineMixin
|
from django.forms.renderers import EngineMixin
|
||||||
from django.utils.datastructures import MultiValueDict
|
from django.utils.datastructures import MultiValueDict
|
||||||
from django.utils.safestring import SafeText
|
from django.utils.safestring import SafeText
|
||||||
|
|
||||||
|
_OptAttrs = Dict[str, str]
|
||||||
|
|
||||||
class MediaOrderConflictWarning(RuntimeWarning): ...
|
class MediaOrderConflictWarning(RuntimeWarning): ...
|
||||||
|
|
||||||
class Media:
|
class Media:
|
||||||
@@ -32,9 +31,7 @@ class Media:
|
|||||||
def __add__(self, other: Media) -> Media: ...
|
def __add__(self, other: Media) -> Media: ...
|
||||||
|
|
||||||
class MediaDefiningClass(type):
|
class MediaDefiningClass(type):
|
||||||
def __new__(
|
def __new__(mcs, name: str, bases: Sequence[Any], attrs: Dict[str, Any]) -> type: ...
|
||||||
mcs: Type[MediaDefiningClass], name: str, bases: Tuple, attrs: Any
|
|
||||||
) -> Type[Union[BaseModelAdmin, BaseForm, Widget]]: ...
|
|
||||||
|
|
||||||
class Widget:
|
class Widget:
|
||||||
needs_multipart_form: bool = ...
|
needs_multipart_form: bool = ...
|
||||||
@@ -61,10 +58,10 @@ class Widget:
|
|||||||
self, base_attrs: Dict[str, Union[float, str]], extra_attrs: Optional[Dict[str, Union[bool, str]]] = ...
|
self, base_attrs: Dict[str, Union[float, str]], extra_attrs: Optional[Dict[str, Union[bool, str]]] = ...
|
||||||
) -> Dict[str, Union[Decimal, float, str]]: ...
|
) -> Dict[str, Union[Decimal, float, str]]: ...
|
||||||
def value_from_datadict(
|
def value_from_datadict(
|
||||||
self, data: dict, files: Union[Dict[str, SimpleUploadedFile], MultiValueDict], name: str
|
self, data: dict, files: Union[Dict[str, Iterable[Any]], MultiValueDict], name: str
|
||||||
) -> Any: ...
|
) -> Any: ...
|
||||||
def value_omitted_from_data(
|
def value_omitted_from_data(
|
||||||
self, data: Dict[str, Any], files: Union[Dict[str, SimpleUploadedFile], MultiValueDict], name: str
|
self, data: Dict[str, Any], files: Union[Dict[str, Iterable[Any]], MultiValueDict], name: str
|
||||||
) -> bool: ...
|
) -> bool: ...
|
||||||
def id_for_label(self, id_: str) -> str: ...
|
def id_for_label(self, id_: str) -> str: ...
|
||||||
def use_required_attribute(self, initial: Any) -> bool: ...
|
def use_required_attribute(self, initial: Any) -> bool: ...
|
||||||
@@ -80,6 +77,7 @@ class URLInput(Input): ...
|
|||||||
|
|
||||||
class PasswordInput(Input):
|
class PasswordInput(Input):
|
||||||
render_value: bool = ...
|
render_value: bool = ...
|
||||||
|
def __init__(self, attrs: Optional[_OptAttrs] = ..., render_value: bool = ...): ...
|
||||||
|
|
||||||
class HiddenInput(Input):
|
class HiddenInput(Input):
|
||||||
choices: Iterable[Tuple[str, str]]
|
choices: Iterable[Tuple[str, str]]
|
||||||
@@ -105,6 +103,7 @@ class DateTimeBaseInput(TextInput):
|
|||||||
format_key: str = ...
|
format_key: str = ...
|
||||||
supports_microseconds: bool = ...
|
supports_microseconds: bool = ...
|
||||||
format: Optional[str] = ...
|
format: Optional[str] = ...
|
||||||
|
def __init__(self, attrs: Optional[_OptAttrs] = ..., format: Optional[str] = ...): ...
|
||||||
|
|
||||||
class DateInput(DateTimeBaseInput): ...
|
class DateInput(DateTimeBaseInput): ...
|
||||||
class DateTimeInput(DateTimeBaseInput): ...
|
class DateTimeInput(DateTimeBaseInput): ...
|
||||||
@@ -112,9 +111,7 @@ class TimeInput(DateTimeBaseInput): ...
|
|||||||
|
|
||||||
class CheckboxInput(Input):
|
class CheckboxInput(Input):
|
||||||
check_test: Callable = ...
|
check_test: Callable = ...
|
||||||
def __init__(self, attrs: Optional[Dict[str, str]] = ..., check_test: Optional[Callable] = ...) -> None: ...
|
def __init__(self, attrs: Optional[_OptAttrs] = ..., check_test: Optional[Callable] = ...) -> None: ...
|
||||||
|
|
||||||
_OptAttrs = Dict[str, Any]
|
|
||||||
|
|
||||||
class ChoiceWidget(Widget):
|
class ChoiceWidget(Widget):
|
||||||
allow_multiple_selected: bool = ...
|
allow_multiple_selected: bool = ...
|
||||||
@@ -165,7 +162,7 @@ class CheckboxSelectMultiple(ChoiceWidget):
|
|||||||
class MultiWidget(Widget):
|
class MultiWidget(Widget):
|
||||||
template_name: str = ...
|
template_name: str = ...
|
||||||
widgets: List[Widget] = ...
|
widgets: List[Widget] = ...
|
||||||
def __init__(self, widgets: Sequence[Widget], attrs: Optional[_OptAttrs] = ...) -> None: ...
|
def __init__(self, widgets: Sequence[Union[Widget, Type[Widget]]], attrs: Optional[_OptAttrs] = ...) -> None: ...
|
||||||
@property
|
@property
|
||||||
def is_hidden(self) -> bool: ...
|
def is_hidden(self) -> bool: ...
|
||||||
def decompress(self, value: Any) -> Optional[Any]: ...
|
def decompress(self, value: Any) -> Optional[Any]: ...
|
||||||
@@ -209,7 +206,7 @@ class SelectDateWidget(Widget):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
attrs: Optional[_OptAttrs] = ...,
|
attrs: Optional[_OptAttrs] = ...,
|
||||||
years: Optional[Union[Tuple[Union[int, str]], range]] = ...,
|
years: Optional[Iterable[Union[int, str]]] = ...,
|
||||||
months: None = ...,
|
months: Optional[Dict[int, str]] = ...,
|
||||||
empty_label: Optional[Union[Tuple[str, str], str]] = ...,
|
empty_label: Optional[Union[str, Sequence[str]]] = ...,
|
||||||
) -> None: ...
|
) -> None: ...
|
||||||
|
|||||||
@@ -1,48 +1,44 @@
|
|||||||
from typing import Any, Callable, Dict, List, Optional, Tuple, Type
|
from typing import Any, Callable, Dict, List, Optional, Type
|
||||||
|
|
||||||
from django import http
|
from django import http
|
||||||
|
|
||||||
logger = ... # type: Any
|
|
||||||
|
|
||||||
class ContextMixin:
|
class ContextMixin:
|
||||||
def get_context_data(self, **kwargs: object) -> Dict[str, Any]: ...
|
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: ...
|
||||||
|
|
||||||
class View:
|
class View:
|
||||||
http_method_names = ... # type: List[str]
|
http_method_names: List[str] = ...
|
||||||
request = ... # type: http.HttpRequest
|
request: http.HttpRequest = ...
|
||||||
args = ... # type: Tuple[object, ...]
|
args: Any = ...
|
||||||
kwargs = ... # type: Dict[str, object]
|
kwargs: Any = ...
|
||||||
def __init__(self, **kwargs: object) -> None: ...
|
def __init__(self, **kwargs: Any) -> None: ...
|
||||||
@classmethod
|
@classmethod
|
||||||
def as_view(cls: Any, **initkwargs: object) -> Callable[..., http.HttpResponse]: ...
|
def as_view(cls: Any, **initkwargs: Any) -> Callable[..., http.HttpResponse]: ...
|
||||||
def dispatch(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
|
def dispatch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
def http_method_not_allowed(
|
def http_method_not_allowed(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
self, request: http.HttpRequest, *args: object, **kwargs: object
|
def options(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
) -> http.HttpResponse: ...
|
|
||||||
def options(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
|
|
||||||
|
|
||||||
class TemplateResponseMixin:
|
class TemplateResponseMixin:
|
||||||
template_name = ... # type: str
|
template_name: str = ...
|
||||||
template_engine = ... # type: Optional[str]
|
template_engine: Optional[str] = ...
|
||||||
response_class = ... # type: Type[http.HttpResponse]
|
response_class: Type[http.HttpResponse] = ...
|
||||||
content_type = ... # type: Optional[str]
|
content_type: Optional[str] = ...
|
||||||
request = ... # type: http.HttpRequest
|
request: http.HttpRequest = ...
|
||||||
def render_to_response(self, context: Dict[str, object], **response_kwargs: object) -> http.HttpResponse: ...
|
def render_to_response(self, context: Dict[str, Any], **response_kwargs: Any) -> http.HttpResponse: ...
|
||||||
def get_template_names(self) -> List[str]: ...
|
def get_template_names(self) -> List[str]: ...
|
||||||
|
|
||||||
class TemplateView(TemplateResponseMixin, ContextMixin, View):
|
class TemplateView(TemplateResponseMixin, ContextMixin, View):
|
||||||
def get(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
|
def get(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
|
|
||||||
class RedirectView(View):
|
class RedirectView(View):
|
||||||
permanent = ... # type: bool
|
permanent: bool = ...
|
||||||
url = ... # type: Optional[str]
|
url: Optional[str] = ...
|
||||||
pattern_name = ... # type: Optional[str]
|
pattern_name: Optional[str] = ...
|
||||||
query_string = ... # type: bool
|
query_string: bool = ...
|
||||||
def get_redirect_url(self, *args: object, **kwargs: object) -> Optional[str]: ...
|
def get_redirect_url(self, *args: Any, **kwargs: Any) -> Optional[str]: ...
|
||||||
def get(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
|
def get(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
def head(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
|
def head(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
def post(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
|
def post(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
def options(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
|
def options(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
def delete(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
|
def delete(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
def put(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
|
def put(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
def patch(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
|
def patch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
|
||||||
|
|||||||
@@ -5,31 +5,30 @@ from django.http import HttpResponse, HttpRequest
|
|||||||
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
|
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
|
||||||
|
|
||||||
class SingleObjectMixin(ContextMixin):
|
class SingleObjectMixin(ContextMixin):
|
||||||
model = ... # type: Optional[Type[models.Model]]
|
model: Optional[Type[models.Model]] = ...
|
||||||
queryset = ... # type: Optional[models.query.QuerySet]
|
queryset: Optional[models.query.QuerySet] = ...
|
||||||
slug_field = ... # type: str
|
slug_field: str = ...
|
||||||
context_object_name = ... # type: Optional[str]
|
context_object_name: Optional[str] = ...
|
||||||
slug_url_kwarg = ... # type: str
|
slug_url_kwarg: str = ...
|
||||||
pk_url_kwarg = ... # type: str
|
pk_url_kwarg: str = ...
|
||||||
query_pk_and_slug = ... # type: bool
|
query_pk_and_slug: bool = ...
|
||||||
object = ... # type: models.Model
|
object: models.Model = ...
|
||||||
kwargs = ... # type: Dict[str, object]
|
kwargs: Dict[str, Any] = ...
|
||||||
def get_object(self, queryset: models.query.QuerySet = None) -> models.Model: ...
|
def get_object(self, queryset: Optional[models.query.QuerySet] = None) -> models.Model: ...
|
||||||
def get_queryset(self) -> models.query.QuerySet: ...
|
def get_queryset(self) -> models.query.QuerySet: ...
|
||||||
def get_slug_field(self) -> str: ...
|
def get_slug_field(self) -> str: ...
|
||||||
def get_context_object_name(self, obj: Any) -> Optional[str]: ...
|
def get_context_object_name(self, obj: Any) -> Optional[str]: ...
|
||||||
def get_context_data(self, **kwargs: object) -> Dict[str, Any]: ...
|
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: ...
|
||||||
|
|
||||||
class BaseDetailView(SingleObjectMixin, View):
|
class BaseDetailView(SingleObjectMixin, View):
|
||||||
def render_to_response(self, context: Dict[str, object], **response_kwargs: object) -> HttpResponse: ...
|
def render_to_response(self, context: Dict[str, Any], **response_kwargs: Any) -> HttpResponse: ...
|
||||||
object = ... # type: models.Model
|
def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
|
||||||
def get(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
|
|
||||||
|
|
||||||
class SingleObjectTemplateResponseMixin(TemplateResponseMixin):
|
class SingleObjectTemplateResponseMixin(TemplateResponseMixin):
|
||||||
template_name_field = ... # type: Optional[str]
|
template_name_field: Optional[str] = ...
|
||||||
template_name_suffix = ... # type: str
|
template_name_suffix: str = ...
|
||||||
model = ... # type: Optional[Type[models.Model]]
|
model: Optional[Type[models.Model]] = ...
|
||||||
object = ... # type: models.Model
|
object: models.Model = ...
|
||||||
def get_template_names(self) -> List[str]: ...
|
def get_template_names(self) -> List[str]: ...
|
||||||
|
|
||||||
class DetailView(SingleObjectTemplateResponseMixin, BaseDetailView): ...
|
class DetailView(SingleObjectTemplateResponseMixin, BaseDetailView): ...
|
||||||
|
|||||||
@@ -1,77 +1,53 @@
|
|||||||
from typing import Any, Callable, Dict, Optional, Sequence, Type, Union
|
from typing import Any, Callable, Dict, Optional, Sequence, Type, Union
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
from django.forms.forms import BaseForm
|
||||||
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
|
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
|
||||||
from django.views.generic.detail import BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin
|
from django.views.generic.detail import BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin
|
||||||
from typing_extensions import Literal
|
from typing_extensions import Literal
|
||||||
|
|
||||||
from django.db import models
|
|
||||||
from django.forms import Form
|
|
||||||
from django.http import HttpRequest, HttpResponse
|
|
||||||
|
|
||||||
class FormMixin(ContextMixin):
|
class FormMixin(ContextMixin):
|
||||||
initial: Dict[str, Any] = ...
|
initial: Dict[str, Any] = ...
|
||||||
form_class: Optional[Type[Form]] = ...
|
form_class: Optional[Type[BaseForm]] = ...
|
||||||
success_url: Optional[Union[str, Callable[..., Any]]] = ...
|
success_url: Optional[Union[str, Callable[..., Any]]] = ...
|
||||||
prefix: Optional[str] = ...
|
prefix: Optional[str] = ...
|
||||||
request: HttpRequest = ...
|
request: HttpRequest = ...
|
||||||
def render_to_response(self, context: Dict[str, Any], **response_kwargs: object) -> HttpResponse: ...
|
def render_to_response(self, context: Dict[str, Any], **response_kwargs: object) -> HttpResponse: ...
|
||||||
def get_initial(self) -> Dict[str, Any]: ...
|
def get_initial(self) -> Dict[str, Any]: ...
|
||||||
def get_prefix(self) -> Optional[str]: ...
|
def get_prefix(self) -> Optional[str]: ...
|
||||||
def get_form_class(self) -> Type[Form]: ...
|
def get_form_class(self) -> Type[BaseForm]: ...
|
||||||
def get_form(self, form_class: Type[Form] = None) -> Form: ...
|
def get_form(self, form_class: Optional[Type[BaseForm]] = None) -> BaseForm: ...
|
||||||
def get_form_kwargs(self) -> Dict[str, Any]: ...
|
def get_form_kwargs(self) -> Dict[str, Any]: ...
|
||||||
def get_success_url(self) -> str: ...
|
def get_success_url(self) -> str: ...
|
||||||
def form_valid(self, form: Form) -> HttpResponse: ...
|
def form_valid(self, form: BaseForm) -> HttpResponse: ...
|
||||||
def form_invalid(self, form: Form) -> HttpResponse: ...
|
def form_invalid(self, form: BaseForm) -> HttpResponse: ...
|
||||||
def get_context_data(self, **kwargs: object) -> Dict[str, Any]: ...
|
|
||||||
|
|
||||||
class ModelFormMixin(FormMixin, SingleObjectMixin):
|
class ModelFormMixin(FormMixin, SingleObjectMixin):
|
||||||
fields: Optional[Union[Sequence[str], Literal["__all__"]]] = ...
|
fields: Optional[Union[Sequence[str], Literal["__all__"]]] = ...
|
||||||
object: models.Model = ...
|
|
||||||
def get_form_class(self) -> Type[Form]: ...
|
|
||||||
def get_form_kwargs(self) -> Dict[str, object]: ...
|
|
||||||
def get_success_url(self) -> str: ...
|
|
||||||
def form_valid(self, form: Form) -> HttpResponse: ...
|
|
||||||
|
|
||||||
class ProcessFormView(View):
|
class ProcessFormView(View):
|
||||||
def render_to_response(self, context: Dict[str, object], **response_kwargs: object) -> HttpResponse: ...
|
def render_to_response(self, context: Dict[str, Any], **response_kwargs: Any) -> HttpResponse: ...
|
||||||
def get_context_data(self, **kwargs: object) -> Dict[str, Any]: ...
|
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: ...
|
||||||
def get_form(self, form_class: Type[Form] = None) -> Form: ...
|
def get(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
|
||||||
def form_valid(self, form: Form) -> HttpResponse: ...
|
def post(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
|
||||||
def form_invalid(self, form: Form) -> HttpResponse: ...
|
def put(self, *args: str, **kwargs: Any) -> HttpResponse: ...
|
||||||
def get(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
|
|
||||||
def post(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
|
|
||||||
def put(self, *args: Any, **kwargs: Any) -> HttpResponse: ...
|
|
||||||
|
|
||||||
class BaseFormView(FormMixin, ProcessFormView): ...
|
class BaseFormView(FormMixin, ProcessFormView): ...
|
||||||
class FormView(TemplateResponseMixin, BaseFormView): ...
|
class FormView(TemplateResponseMixin, BaseFormView): ...
|
||||||
|
class BaseCreateView(ModelFormMixin, ProcessFormView): ...
|
||||||
class BaseCreateView(ModelFormMixin, ProcessFormView):
|
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView): ...
|
||||||
object = ... # type: models.Model
|
class BaseUpdateView(ModelFormMixin, ProcessFormView): ...
|
||||||
def get(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
|
class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView): ...
|
||||||
def post(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
|
|
||||||
|
|
||||||
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView):
|
|
||||||
template_name_suffix = ... # type: str
|
|
||||||
|
|
||||||
class BaseUpdateView(ModelFormMixin, ProcessFormView):
|
|
||||||
object = ... # type: models.Model
|
|
||||||
def get(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
|
|
||||||
def post(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
|
|
||||||
|
|
||||||
class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView):
|
|
||||||
template_name_suffix = ... # type: str
|
|
||||||
|
|
||||||
_object = object
|
_object = object
|
||||||
|
|
||||||
class DeletionMixin:
|
class DeletionMixin:
|
||||||
success_url = ... # type: Optional[str]
|
success_url: Optional[str] = ...
|
||||||
object = ... # type: models.Model
|
object: models.Model = ...
|
||||||
def delete(self, request: HttpRequest, *args: _object, **kwargs: _object) -> HttpResponse: ...
|
def post(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
|
||||||
def post(self, request: HttpRequest, *args: _object, **kwargs: _object) -> HttpResponse: ...
|
def delete(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
|
||||||
def get_success_url(self) -> str: ...
|
def get_success_url(self) -> str: ...
|
||||||
|
|
||||||
class BaseDeleteView(DeletionMixin, BaseDetailView): ...
|
class BaseDeleteView(DeletionMixin, BaseDetailView): ...
|
||||||
|
class DeleteView(SingleObjectTemplateResponseMixin, BaseDeleteView): ...
|
||||||
class DeleteView(SingleObjectTemplateResponseMixin, BaseDeleteView):
|
|
||||||
template_name_suffix = ... # type: str
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ QUERYSET_CLASS_FULLNAME = 'django.db.models.query.QuerySet'
|
|||||||
BASE_MANAGER_CLASS_FULLNAME = 'django.db.models.manager.BaseManager'
|
BASE_MANAGER_CLASS_FULLNAME = 'django.db.models.manager.BaseManager'
|
||||||
MANAGER_CLASS_FULLNAME = 'django.db.models.manager.Manager'
|
MANAGER_CLASS_FULLNAME = 'django.db.models.manager.Manager'
|
||||||
RELATED_MANAGER_CLASS_FULLNAME = 'django.db.models.manager.RelatedManager'
|
RELATED_MANAGER_CLASS_FULLNAME = 'django.db.models.manager.RelatedManager'
|
||||||
|
MODELFORM_CLASS_FULLNAME = 'django.forms.models.ModelForm'
|
||||||
|
|
||||||
MANAGER_CLASSES = {
|
MANAGER_CLASSES = {
|
||||||
MANAGER_CLASS_FULLNAME,
|
MANAGER_CLASS_FULLNAME,
|
||||||
@@ -54,9 +55,9 @@ def get_model_fullname(app_name: str, model_name: str,
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class InvalidModelString(ValueError):
|
class SameFileModel(Exception):
|
||||||
def __init__(self, model_string: str):
|
def __init__(self, model_cls_name: str):
|
||||||
self.model_string = model_string
|
self.model_cls_name = model_cls_name
|
||||||
|
|
||||||
|
|
||||||
class SelfReference(ValueError):
|
class SelfReference(ValueError):
|
||||||
@@ -69,7 +70,7 @@ def get_model_fullname_from_string(model_string: str,
|
|||||||
raise SelfReference()
|
raise SelfReference()
|
||||||
|
|
||||||
if '.' not in model_string:
|
if '.' not in model_string:
|
||||||
raise InvalidModelString(model_string)
|
raise SameFileModel(model_string)
|
||||||
|
|
||||||
app_name, model_name = model_string.split('.')
|
app_name, model_name = model_string.split('.')
|
||||||
return get_model_fullname(app_name, model_name, all_modules)
|
return get_model_fullname(app_name, model_name, all_modules)
|
||||||
@@ -246,7 +247,7 @@ def extract_primary_key_type_for_get(model: TypeInfo) -> Optional[Type]:
|
|||||||
|
|
||||||
|
|
||||||
def make_optional(typ: Type):
|
def make_optional(typ: Type):
|
||||||
return UnionType.make_simplified_union([typ, NoneTyp()])
|
return UnionType.make_union([typ, NoneTyp()])
|
||||||
|
|
||||||
|
|
||||||
def make_required(typ: Type) -> Type:
|
def make_required(typ: Type) -> Type:
|
||||||
@@ -273,3 +274,10 @@ def has_any_of_bases(info: TypeInfo, bases: typing.Sequence[str]) -> bool:
|
|||||||
|
|
||||||
def is_none_expr(expr: Expression) -> bool:
|
def is_none_expr(expr: Expression) -> bool:
|
||||||
return isinstance(expr, NameExpr) and expr.fullname == 'builtins.None'
|
return isinstance(expr, NameExpr) and expr.fullname == 'builtins.None'
|
||||||
|
|
||||||
|
|
||||||
|
def get_nested_meta_node_for_current_class(info: TypeInfo) -> Optional[TypeInfo]:
|
||||||
|
metaclass_sym = info.names.get('Meta')
|
||||||
|
if metaclass_sym is not None and isinstance(metaclass_sym.node, TypeInfo):
|
||||||
|
return metaclass_sym.node
|
||||||
|
return None
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ from mypy.nodes import MemberExpr, TypeInfo
|
|||||||
from mypy.options import Options
|
from mypy.options import Options
|
||||||
from mypy.plugin import AttributeContext, ClassDefContext, FunctionContext, MethodContext, Plugin
|
from mypy.plugin import AttributeContext, ClassDefContext, FunctionContext, MethodContext, Plugin
|
||||||
from mypy.types import AnyType, Instance, Type, TypeOfAny, TypeType, UnionType
|
from mypy.types import AnyType, Instance, Type, TypeOfAny, TypeType, UnionType
|
||||||
|
|
||||||
from mypy_django_plugin import helpers, monkeypatch
|
from mypy_django_plugin import helpers, monkeypatch
|
||||||
from mypy_django_plugin.config import Config
|
from mypy_django_plugin.config import Config
|
||||||
from mypy_django_plugin.transformers import fields, init_create
|
from mypy_django_plugin.transformers import fields, init_create
|
||||||
|
from mypy_django_plugin.transformers.forms import make_meta_nested_class_inherit_from_any
|
||||||
from mypy_django_plugin.transformers.migrations import determine_model_cls_from_string_for_migrations, \
|
from mypy_django_plugin.transformers.migrations import determine_model_cls_from_string_for_migrations, \
|
||||||
get_string_value_from_expr
|
get_string_value_from_expr
|
||||||
from mypy_django_plugin.transformers.models import process_model_class
|
from mypy_django_plugin.transformers.models import process_model_class
|
||||||
@@ -33,6 +35,14 @@ def transform_manager_class(ctx: ClassDefContext) -> None:
|
|||||||
sym.node.metadata['django']['manager_bases'][ctx.cls.fullname] = 1
|
sym.node.metadata['django']['manager_bases'][ctx.cls.fullname] = 1
|
||||||
|
|
||||||
|
|
||||||
|
def transform_modelform_class(ctx: ClassDefContext) -> None:
|
||||||
|
sym = ctx.api.lookup_fully_qualified_or_none(helpers.MODELFORM_CLASS_FULLNAME)
|
||||||
|
if sym is not None and isinstance(sym.node, TypeInfo):
|
||||||
|
sym.node.metadata['django']['modelform_bases'][ctx.cls.fullname] = 1
|
||||||
|
|
||||||
|
make_meta_nested_class_inherit_from_any(ctx)
|
||||||
|
|
||||||
|
|
||||||
def determine_proper_manager_type(ctx: FunctionContext) -> Type:
|
def determine_proper_manager_type(ctx: FunctionContext) -> Type:
|
||||||
api = cast(TypeChecker, ctx.api)
|
api = cast(TypeChecker, ctx.api)
|
||||||
ret = ctx.default_return_type
|
ret = ctx.default_return_type
|
||||||
@@ -176,31 +186,32 @@ class DjangoPlugin(Plugin):
|
|||||||
def _get_current_model_bases(self) -> Dict[str, int]:
|
def _get_current_model_bases(self) -> Dict[str, int]:
|
||||||
model_sym = self.lookup_fully_qualified(helpers.MODEL_CLASS_FULLNAME)
|
model_sym = self.lookup_fully_qualified(helpers.MODEL_CLASS_FULLNAME)
|
||||||
if model_sym is not None and isinstance(model_sym.node, TypeInfo):
|
if model_sym is not None and isinstance(model_sym.node, TypeInfo):
|
||||||
if 'django' not in model_sym.node.metadata:
|
return (model_sym.node.metadata
|
||||||
model_sym.node.metadata['django'] = {
|
.setdefault('django', {})
|
||||||
'model_bases': {helpers.MODEL_CLASS_FULLNAME: 1}
|
.setdefault('model_bases', {helpers.MODEL_CLASS_FULLNAME: 1}))
|
||||||
}
|
|
||||||
return model_sym.node.metadata['django']['model_bases']
|
|
||||||
else:
|
else:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def _get_current_manager_bases(self) -> Dict[str, int]:
|
def _get_current_manager_bases(self) -> Dict[str, int]:
|
||||||
manager_sym = self.lookup_fully_qualified(helpers.MANAGER_CLASS_FULLNAME)
|
model_sym = self.lookup_fully_qualified(helpers.MANAGER_CLASS_FULLNAME)
|
||||||
if manager_sym is not None and isinstance(manager_sym.node, TypeInfo):
|
if model_sym is not None and isinstance(model_sym.node, TypeInfo):
|
||||||
if 'django' not in manager_sym.node.metadata:
|
return (model_sym.node.metadata
|
||||||
manager_sym.node.metadata['django'] = {
|
.setdefault('django', {})
|
||||||
'manager_bases': {helpers.MANAGER_CLASS_FULLNAME: 1}
|
.setdefault('manager_bases', {helpers.MANAGER_CLASS_FULLNAME: 1}))
|
||||||
}
|
else:
|
||||||
return manager_sym.node.metadata['django']['manager_bases']
|
return {}
|
||||||
|
|
||||||
|
def _get_current_modelform_bases(self) -> Dict[str, int]:
|
||||||
|
model_sym = self.lookup_fully_qualified(helpers.MODELFORM_CLASS_FULLNAME)
|
||||||
|
if model_sym is not None and isinstance(model_sym.node, TypeInfo):
|
||||||
|
return (model_sym.node.metadata
|
||||||
|
.setdefault('django', {})
|
||||||
|
.setdefault('modelform_bases', {helpers.MODELFORM_CLASS_FULLNAME: 1}))
|
||||||
else:
|
else:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def get_function_hook(self, fullname: str
|
def get_function_hook(self, fullname: str
|
||||||
) -> Optional[Callable[[FunctionContext], Type]]:
|
) -> Optional[Callable[[FunctionContext], Type]]:
|
||||||
sym = self.lookup_fully_qualified(fullname)
|
|
||||||
if sym and isinstance(sym.node, TypeInfo) and sym.node.has_base(helpers.FIELD_FULLNAME):
|
|
||||||
return fields.adjust_return_type_of_field_instantiation
|
|
||||||
|
|
||||||
if fullname == 'django.contrib.auth.get_user_model':
|
if fullname == 'django.contrib.auth.get_user_model':
|
||||||
return return_user_model_hook
|
return return_user_model_hook
|
||||||
|
|
||||||
@@ -209,27 +220,27 @@ class DjangoPlugin(Plugin):
|
|||||||
return determine_proper_manager_type
|
return determine_proper_manager_type
|
||||||
|
|
||||||
sym = self.lookup_fully_qualified(fullname)
|
sym = self.lookup_fully_qualified(fullname)
|
||||||
if sym and isinstance(sym.node, TypeInfo):
|
if sym is not None and isinstance(sym.node, TypeInfo):
|
||||||
|
if sym.node.has_base(helpers.FIELD_FULLNAME):
|
||||||
|
return fields.adjust_return_type_of_field_instantiation
|
||||||
|
|
||||||
if sym.node.metadata.get('django', {}).get('generated_init'):
|
if sym.node.metadata.get('django', {}).get('generated_init'):
|
||||||
return init_create.redefine_and_typecheck_model_init
|
return init_create.redefine_and_typecheck_model_init
|
||||||
|
|
||||||
def get_method_hook(self, fullname: str
|
def get_method_hook(self, fullname: str
|
||||||
) -> Optional[Callable[[MethodContext], Type]]:
|
) -> Optional[Callable[[MethodContext], Type]]:
|
||||||
|
if fullname in {'django.apps.registry.Apps.get_model',
|
||||||
|
'django.db.migrations.state.StateApps.get_model'}:
|
||||||
|
return determine_model_cls_from_string_for_migrations
|
||||||
|
|
||||||
manager_classes = self._get_current_manager_bases()
|
manager_classes = self._get_current_manager_bases()
|
||||||
class_fullname, _, method_name = fullname.rpartition('.')
|
class_fullname, _, method_name = fullname.rpartition('.')
|
||||||
if class_fullname in manager_classes and method_name == 'create':
|
if class_fullname in manager_classes and method_name == 'create':
|
||||||
return init_create.redefine_and_typecheck_model_create
|
return init_create.redefine_and_typecheck_model_create
|
||||||
|
|
||||||
if fullname in {'django.apps.registry.Apps.get_model',
|
|
||||||
'django.db.migrations.state.StateApps.get_model'}:
|
|
||||||
return determine_model_cls_from_string_for_migrations
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_base_class_hook(self, fullname: str
|
def get_base_class_hook(self, fullname: str
|
||||||
) -> Optional[Callable[[ClassDefContext], None]]:
|
) -> Optional[Callable[[ClassDefContext], None]]:
|
||||||
if fullname in self._get_current_model_bases():
|
|
||||||
return transform_model_class
|
|
||||||
|
|
||||||
if fullname == helpers.DUMMY_SETTINGS_BASE_CLASS:
|
if fullname == helpers.DUMMY_SETTINGS_BASE_CLASS:
|
||||||
settings_modules = ['django.conf.global_settings']
|
settings_modules = ['django.conf.global_settings']
|
||||||
if self.django_settings_module:
|
if self.django_settings_module:
|
||||||
@@ -237,13 +248,22 @@ class DjangoPlugin(Plugin):
|
|||||||
return AddSettingValuesToDjangoConfObject(settings_modules,
|
return AddSettingValuesToDjangoConfObject(settings_modules,
|
||||||
self.config.ignore_missing_settings)
|
self.config.ignore_missing_settings)
|
||||||
|
|
||||||
|
if fullname in self._get_current_model_bases():
|
||||||
|
return transform_model_class
|
||||||
|
|
||||||
if fullname in self._get_current_manager_bases():
|
if fullname in self._get_current_manager_bases():
|
||||||
return transform_manager_class
|
return transform_manager_class
|
||||||
|
|
||||||
|
if fullname in self._get_current_modelform_bases():
|
||||||
|
return transform_modelform_class
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_attribute_hook(self, fullname: str
|
def get_attribute_hook(self, fullname: str
|
||||||
) -> Optional[Callable[[AttributeContext], Type]]:
|
) -> Optional[Callable[[AttributeContext], Type]]:
|
||||||
|
if fullname == 'builtins.object.id':
|
||||||
|
return return_integer_type_for_id_for_non_defined_primary_key_in_models
|
||||||
|
|
||||||
module, _, name = fullname.rpartition('.')
|
module, _, name = fullname.rpartition('.')
|
||||||
sym = self.lookup_fully_qualified('django.conf.LazySettings')
|
sym = self.lookup_fully_qualified('django.conf.LazySettings')
|
||||||
if sym and isinstance(sym.node, TypeInfo):
|
if sym and isinstance(sym.node, TypeInfo):
|
||||||
@@ -251,9 +271,6 @@ class DjangoPlugin(Plugin):
|
|||||||
if module == 'builtins.object' and name in metadata:
|
if module == 'builtins.object' and name in metadata:
|
||||||
return ExtractSettingType(module_fullname=metadata[name])
|
return ExtractSettingType(module_fullname=metadata[name])
|
||||||
|
|
||||||
if fullname == 'builtins.object.id':
|
|
||||||
return return_integer_type_for_id_for_non_defined_primary_key_in_models
|
|
||||||
|
|
||||||
return extract_and_return_primary_key_of_bound_related_field_parameter
|
return extract_and_return_primary_key_of_bound_related_field_parameter
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from mypy_django_plugin import helpers
|
|||||||
from mypy_django_plugin.transformers.models import iter_over_assignments
|
from mypy_django_plugin.transformers.models import iter_over_assignments
|
||||||
|
|
||||||
|
|
||||||
def get_valid_to_value_or_none(ctx: FunctionContext) -> Optional[Instance]:
|
def extract_referred_to_type(ctx: FunctionContext) -> Optional[Instance]:
|
||||||
api = cast(TypeChecker, ctx.api)
|
api = cast(TypeChecker, ctx.api)
|
||||||
if 'to' not in ctx.callee_arg_names:
|
if 'to' not in ctx.callee_arg_names:
|
||||||
api.msg.fail(f'to= parameter must be set for {ctx.context.callee.fullname}',
|
api.msg.fail(f'to= parameter must be set for {ctx.context.callee.fullname}',
|
||||||
@@ -27,6 +27,9 @@ def get_valid_to_value_or_none(ctx: FunctionContext) -> Optional[Instance]:
|
|||||||
except helpers.SelfReference:
|
except helpers.SelfReference:
|
||||||
model_fullname = api.tscope.classes[-1].fullname()
|
model_fullname = api.tscope.classes[-1].fullname()
|
||||||
|
|
||||||
|
except helpers.SameFileModel as exc:
|
||||||
|
model_fullname = api.tscope.classes[-1].module_name + '.' + exc.model_cls_name
|
||||||
|
|
||||||
if model_fullname is None:
|
if model_fullname is None:
|
||||||
return None
|
return None
|
||||||
model_info = helpers.lookup_fully_qualified_generic(model_fullname,
|
model_info = helpers.lookup_fully_qualified_generic(model_fullname,
|
||||||
@@ -52,8 +55,8 @@ def convert_any_to_type(typ: Type, referred_to_type: Type) -> Type:
|
|||||||
converted_items = []
|
converted_items = []
|
||||||
for item in typ.items:
|
for item in typ.items:
|
||||||
converted_items.append(convert_any_to_type(item, referred_to_type))
|
converted_items.append(convert_any_to_type(item, referred_to_type))
|
||||||
return UnionType.make_simplified_union(converted_items,
|
return UnionType.make_union(converted_items,
|
||||||
line=typ.line, column=typ.column)
|
line=typ.line, column=typ.column)
|
||||||
if isinstance(typ, Instance):
|
if isinstance(typ, Instance):
|
||||||
args = []
|
args = []
|
||||||
for default_arg in typ.args:
|
for default_arg in typ.args:
|
||||||
@@ -69,19 +72,9 @@ def convert_any_to_type(typ: Type, referred_to_type: Type) -> Type:
|
|||||||
return typ
|
return typ
|
||||||
|
|
||||||
|
|
||||||
def _extract_referred_to_type(ctx: FunctionContext) -> Optional[Type]:
|
|
||||||
try:
|
|
||||||
referred_to_type = get_valid_to_value_or_none(ctx)
|
|
||||||
except helpers.InvalidModelString as exc:
|
|
||||||
ctx.api.fail(f'Invalid value for a to= parameter: {exc.model_string!r}', ctx.context)
|
|
||||||
return None
|
|
||||||
|
|
||||||
return referred_to_type
|
|
||||||
|
|
||||||
|
|
||||||
def fill_descriptor_types_for_related_field(ctx: FunctionContext) -> Type:
|
def fill_descriptor_types_for_related_field(ctx: FunctionContext) -> Type:
|
||||||
default_return_type = set_descriptor_types_for_field(ctx)
|
default_return_type = set_descriptor_types_for_field(ctx)
|
||||||
referred_to_type = _extract_referred_to_type(ctx)
|
referred_to_type = extract_referred_to_type(ctx)
|
||||||
if referred_to_type is None:
|
if referred_to_type is None:
|
||||||
return default_return_type
|
return default_return_type
|
||||||
|
|
||||||
|
|||||||
9
mypy_django_plugin/transformers/forms.py
Normal file
9
mypy_django_plugin/transformers/forms.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from mypy.plugin import ClassDefContext
|
||||||
|
from mypy_django_plugin import helpers
|
||||||
|
|
||||||
|
|
||||||
|
def make_meta_nested_class_inherit_from_any(ctx: ClassDefContext) -> None:
|
||||||
|
meta_node = helpers.get_nested_meta_node_for_current_class(ctx.cls.info)
|
||||||
|
if meta_node is None:
|
||||||
|
return None
|
||||||
|
meta_node.fallback_to_any = True
|
||||||
@@ -2,7 +2,7 @@ from abc import ABCMeta, abstractmethod
|
|||||||
from typing import Dict, Iterator, List, Optional, Tuple, cast
|
from typing import Dict, Iterator, List, Optional, Tuple, cast
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
from mypy.nodes import ARG_STAR, ARG_STAR2, Argument, CallExpr, ClassDef, Context, Expression, IndexExpr, \
|
from mypy.nodes import ARG_STAR, ARG_STAR2, Argument, CallExpr, ClassDef, Expression, IndexExpr, \
|
||||||
Lvalue, MDEF, MemberExpr, MypyFile, NameExpr, StrExpr, SymbolTableNode, TypeInfo, Var
|
Lvalue, MDEF, MemberExpr, MypyFile, NameExpr, StrExpr, SymbolTableNode, TypeInfo, Var
|
||||||
from mypy.plugin import ClassDefContext
|
from mypy.plugin import ClassDefContext
|
||||||
from mypy.plugins.common import add_method
|
from mypy.plugins.common import add_method
|
||||||
@@ -21,14 +21,8 @@ class ModelClassInitializer(metaclass=ABCMeta):
|
|||||||
def from_ctx(cls, ctx: ClassDefContext):
|
def from_ctx(cls, ctx: ClassDefContext):
|
||||||
return cls(api=cast(SemanticAnalyzerPass2, ctx.api), model_classdef=ctx.cls)
|
return cls(api=cast(SemanticAnalyzerPass2, ctx.api), model_classdef=ctx.cls)
|
||||||
|
|
||||||
def get_nested_meta_node(self) -> Optional[TypeInfo]:
|
|
||||||
metaclass_sym = self.model_classdef.info.names.get('Meta')
|
|
||||||
if metaclass_sym is not None and isinstance(metaclass_sym.node, TypeInfo):
|
|
||||||
return metaclass_sym.node
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_meta_attribute(self, name: str) -> Optional[Expression]:
|
def get_meta_attribute(self, name: str) -> Optional[Expression]:
|
||||||
meta_node = self.get_nested_meta_node()
|
meta_node = helpers.get_nested_meta_node_for_current_class(self.model_classdef.info)
|
||||||
if meta_node is None:
|
if meta_node is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -80,7 +74,7 @@ class SetIdAttrsForRelatedFields(ModelClassInitializer):
|
|||||||
|
|
||||||
class InjectAnyAsBaseForNestedMeta(ModelClassInitializer):
|
class InjectAnyAsBaseForNestedMeta(ModelClassInitializer):
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
meta_node = self.get_nested_meta_node()
|
meta_node = helpers.get_nested_meta_node_for_current_class(self.model_classdef.info)
|
||||||
if meta_node is None:
|
if meta_node is None:
|
||||||
return None
|
return None
|
||||||
meta_node.fallback_to_any = True
|
meta_node.fallback_to_any = True
|
||||||
@@ -173,10 +167,9 @@ class AddRelatedManagers(ModelClassInitializer):
|
|||||||
all_modules=self.api.modules)
|
all_modules=self.api.modules)
|
||||||
except helpers.SelfReference:
|
except helpers.SelfReference:
|
||||||
ref_to_fullname = defn.fullname
|
ref_to_fullname = defn.fullname
|
||||||
except helpers.InvalidModelString as exc:
|
|
||||||
self.api.fail(f'Invalid value for a to= parameter: {exc.model_string!r}',
|
except helpers.SameFileModel as exc:
|
||||||
Context(line=rvalue.line))
|
ref_to_fullname = module_name + '.' + exc.model_cls_name
|
||||||
return None
|
|
||||||
|
|
||||||
if self.model_classdef.fullname == ref_to_fullname:
|
if self.model_classdef.fullname == ref_to_fullname:
|
||||||
related_manager_name = defn.name.lower() + '_set'
|
related_manager_name = defn.name.lower() + '_set'
|
||||||
|
|||||||
@@ -4,6 +4,5 @@ testpaths = ./test-data
|
|||||||
addopts =
|
addopts =
|
||||||
--tb=native
|
--tb=native
|
||||||
--mypy-ini-file=./test-data/plugins.ini
|
--mypy-ini-file=./test-data/plugins.ini
|
||||||
--mypy-no-cache
|
|
||||||
-s
|
-s
|
||||||
-v
|
-v
|
||||||
@@ -32,7 +32,7 @@ IGNORED_ERRORS = {
|
|||||||
'Cannot assign to a type',
|
'Cannot assign to a type',
|
||||||
re.compile(r'Cannot assign to class variable "[a-z_]+" via instance'),
|
re.compile(r'Cannot assign to class variable "[a-z_]+" via instance'),
|
||||||
# forms <-> models plugin support
|
# forms <-> models plugin support
|
||||||
'"Model" has no attribute',
|
# '"Model" has no attribute',
|
||||||
re.compile(r'Cannot determine type of \'(objects|stuff)\''),
|
re.compile(r'Cannot determine type of \'(objects|stuff)\''),
|
||||||
# settings
|
# settings
|
||||||
re.compile(r'Module has no attribute "[A-Z_]+"'),
|
re.compile(r'Module has no attribute "[A-Z_]+"'),
|
||||||
@@ -54,7 +54,8 @@ IGNORED_ERRORS = {
|
|||||||
'ValuesIterable',
|
'ValuesIterable',
|
||||||
'Value of type "Optional[Dict[str, Any]]" is not indexable',
|
'Value of type "Optional[Dict[str, Any]]" is not indexable',
|
||||||
'Argument 1 to "len" has incompatible type "Optional[List[_Record]]"; expected "Sized"',
|
'Argument 1 to "len" has incompatible type "Optional[List[_Record]]"; expected "Sized"',
|
||||||
'Argument 1 to "loads" has incompatible type "Union[bytes, str, None]"; expected "Union[str, bytes, bytearray]"'
|
'Argument 1 to "loads" has incompatible type "Union[bytes, str, None]"; expected "Union[str, bytes, bytearray]"',
|
||||||
|
'Incompatible types in assignment (expression has type "None", variable has type Module)'
|
||||||
],
|
],
|
||||||
'admin_changelist': [
|
'admin_changelist': [
|
||||||
'Incompatible types in assignment (expression has type "FilteredChildAdmin", variable has type "ChildAdmin")'
|
'Incompatible types in assignment (expression has type "FilteredChildAdmin", variable has type "ChildAdmin")'
|
||||||
@@ -166,6 +167,29 @@ IGNORED_ERRORS = {
|
|||||||
'fixtures': [
|
'fixtures': [
|
||||||
'Incompatible types in assignment (expression has type "int", target has type "Iterable[str]")'
|
'Incompatible types in assignment (expression has type "int", target has type "Iterable[str]")'
|
||||||
],
|
],
|
||||||
|
'forms_tests': [
|
||||||
|
'List item 0 has incompatible type "Jinja2"; expected "DjangoTemplates"',
|
||||||
|
'Not enough arguments for format string',
|
||||||
|
'Argument after ** must be a mapping, not "object"',
|
||||||
|
'"media" undefined in superclass',
|
||||||
|
'expression has type "None", base class "TestFormParent"',
|
||||||
|
'variable has type "SongForm"',
|
||||||
|
'"full_clean" of "BaseForm" does not return a value',
|
||||||
|
'No overload variant of "zip" matches argument types "Tuple[str, str, str]", "object"',
|
||||||
|
'note:',
|
||||||
|
'Incompatible types in assignment (expression has type "GetDateShowHiddenInitial", variable has type "GetDate")',
|
||||||
|
re.compile(r'Incompatible types in assignment \(expression has type "[a-zA-Z]+Field", '
|
||||||
|
r'base class "BaseForm" defined the type as "Dict\[str, Any\]"\)'),
|
||||||
|
'List or tuple expected as variable arguments',
|
||||||
|
'Argument 1 to "__init__" of "MultiWidget" has incompatible type "List[object]"; '
|
||||||
|
+ 'expected "Sequence[Union[Widget, Type[Widget]]]"',
|
||||||
|
'Argument 1 to "issubclass" has incompatible type "ModelFormMetaclass"; expected "type"',
|
||||||
|
'Incompatible types in assignment (expression has type "List[str]", target has type "str")',
|
||||||
|
'Incompatible types in assignment (expression has type "TestForm", variable has type "Person")',
|
||||||
|
'Incompatible types in assignment (expression has type "Type[Textarea]", '
|
||||||
|
+ 'base class "Field" defined the type as "Widget")',
|
||||||
|
'Incompatible types in assignment (expression has type "SimpleUploadedFile", variable has type "BinaryIO")'
|
||||||
|
],
|
||||||
'get_object_or_404': [
|
'get_object_or_404': [
|
||||||
'Argument 1 to "get_object_or_404" has incompatible type "str"; '
|
'Argument 1 to "get_object_or_404" has incompatible type "str"; '
|
||||||
+ 'expected "Union[Type[<nothing>], Manager[<nothing>], QuerySet[<nothing>]]"',
|
+ 'expected "Union[Type[<nothing>], Manager[<nothing>], QuerySet[<nothing>]]"',
|
||||||
@@ -208,6 +232,12 @@ IGNORED_ERRORS = {
|
|||||||
+ 'base class "ImageFieldTestMixin" defined the type as "Type[PersonWithHeightAndWidth]")',
|
+ 'base class "ImageFieldTestMixin" defined the type as "Type[PersonWithHeightAndWidth]")',
|
||||||
'note: "Person" defined here'
|
'note: "Person" defined here'
|
||||||
],
|
],
|
||||||
|
'model_formsets': [
|
||||||
|
'Incompatible types in string interpolation (expression has type "object", placeholder has type "Union[int, float]")'
|
||||||
|
],
|
||||||
|
'model_formsets_regress': [
|
||||||
|
'Incompatible types in assignment (expression has type "Model", variable has type "User")'
|
||||||
|
],
|
||||||
'model_regress': [
|
'model_regress': [
|
||||||
'Too many arguments for "Worker"',
|
'Too many arguments for "Worker"',
|
||||||
re.compile(r'Incompatible type for "[a-z]+" of "Worker" \(got "int", expected')
|
re.compile(r'Incompatible type for "[a-z]+" of "Worker" \(got "int", expected')
|
||||||
@@ -286,7 +316,8 @@ IGNORED_ERRORS = {
|
|||||||
],
|
],
|
||||||
'schema': [
|
'schema': [
|
||||||
'Incompatible type for "info" of "Note" (got "None", expected "Union[str, Combinable]")',
|
'Incompatible type for "info" of "Note" (got "None", expected "Union[str, Combinable]")',
|
||||||
'Incompatible type for "detail_info" of "NoteRename" (got "None", expected "Union[str, Combinable]")'
|
'Incompatible type for "detail_info" of "NoteRename" (got "None", expected "Union[str, Combinable]")',
|
||||||
|
'Incompatible type for "year" of "UniqueTest" (got "None", expected "Union[float, int, str, Combinable]")'
|
||||||
],
|
],
|
||||||
'settings_tests': [
|
'settings_tests': [
|
||||||
'Argument 1 to "Settings" has incompatible type "Optional[str]"; expected "str"'
|
'Argument 1 to "Settings" has incompatible type "Optional[str]"; expected "str"'
|
||||||
@@ -329,7 +360,6 @@ IGNORED_ERRORS = {
|
|||||||
'template_backends': [
|
'template_backends': [
|
||||||
'Incompatible import of "Jinja2" (imported name has type "Type[Jinja2]", local name has type "object")',
|
'Incompatible import of "Jinja2" (imported name has type "Type[Jinja2]", local name has type "object")',
|
||||||
'TemplateStringsTests',
|
'TemplateStringsTests',
|
||||||
'Incompatible types in assignment (expression has type "None", variable has type Module)'
|
|
||||||
],
|
],
|
||||||
'urlpatterns': [
|
'urlpatterns': [
|
||||||
'"object" has no attribute "__iter__"; maybe "__str__" or "__dir__"? (not iterable)',
|
'"object" has no attribute "__iter__"; maybe "__str__" or "__dir__"? (not iterable)',
|
||||||
@@ -348,7 +378,7 @@ IGNORED_ERRORS = {
|
|||||||
],
|
],
|
||||||
'sessions_tests': [
|
'sessions_tests': [
|
||||||
'base class "SessionTestsMixin" defined the type as "None")',
|
'base class "SessionTestsMixin" defined the type as "None")',
|
||||||
'Incompatible types in assignment (expression has type "None", variable has type "int")'
|
'Incompatible types in assignment (expression has type "None", variable has type "int")',
|
||||||
],
|
],
|
||||||
'select_related_onetoone': [
|
'select_related_onetoone': [
|
||||||
'"None" has no attribute'
|
'"None" has no attribute'
|
||||||
@@ -439,7 +469,7 @@ TESTS_DIRS = [
|
|||||||
'flatpages_tests',
|
'flatpages_tests',
|
||||||
'force_insert_update',
|
'force_insert_update',
|
||||||
'foreign_object',
|
'foreign_object',
|
||||||
# TODO: 'forms_tests',
|
'forms_tests',
|
||||||
'from_db_value',
|
'from_db_value',
|
||||||
'generic_inline_admin',
|
'generic_inline_admin',
|
||||||
'generic_relations',
|
'generic_relations',
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -31,7 +31,7 @@ if sys.version_info[:2] < (3, 7):
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="django-stubs",
|
name="django-stubs",
|
||||||
version="0.5.1",
|
version="0.7.0",
|
||||||
description='Django mypy stubs',
|
description='Django mypy stubs',
|
||||||
long_description=readme,
|
long_description=readme,
|
||||||
long_description_content_type='text/markdown',
|
long_description_content_type='text/markdown',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[mypy]
|
[mypy]
|
||||||
incremental = False
|
incremental = True
|
||||||
strict_optional = True
|
strict_optional = True
|
||||||
plugins =
|
plugins =
|
||||||
mypy_django_plugin.main
|
mypy_django_plugin.main
|
||||||
|
|||||||
@@ -1,28 +1,30 @@
|
|||||||
[CASE missing_settings_ignored_flag]
|
[CASE missing_settings_ignored_flag]
|
||||||
|
[env MYPY_DJANGO_CONFIG=${MYPY_CWD}/mypy_django.ini]
|
||||||
|
[disable_cache]
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
reveal_type(settings.NO_SUCH_SETTING) # E: Revealed type is 'Any'
|
reveal_type(settings.NO_SUCH_SETTING) # E: Revealed type is 'Any'
|
||||||
|
|
||||||
[env MYPY_DJANGO_CONFIG=${MYPY_CWD}/mypy_django.ini]
|
|
||||||
|
|
||||||
[file mypy_django.ini]
|
[file mypy_django.ini]
|
||||||
[[mypy_django_plugin]
|
[[mypy_django_plugin]
|
||||||
ignore_missing_settings = True
|
ignore_missing_settings = True
|
||||||
[out]
|
[/CASE]
|
||||||
|
|
||||||
[CASE django_settings_via_config_file]
|
[CASE django_settings_via_config_file]
|
||||||
|
[env MYPY_DJANGO_CONFIG=${MYPY_CWD}/mypy_django.ini]
|
||||||
|
[disable_cache]
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
reveal_type(settings.MY_SETTING) # E: Revealed type is 'builtins.int'
|
reveal_type(settings.MY_SETTING) # E: Revealed type is 'builtins.int'
|
||||||
|
|
||||||
[env MYPY_DJANGO_CONFIG=${MYPY_CWD}/mypy_django.ini]
|
|
||||||
[file mypy_django.ini]
|
[file mypy_django.ini]
|
||||||
[[mypy_django_plugin]
|
[[mypy_django_plugin]
|
||||||
django_settings = mysettings
|
django_settings = mysettings
|
||||||
|
|
||||||
[file mysettings.py]
|
[file mysettings.py]
|
||||||
MY_SETTING: int = 1
|
MY_SETTING: int = 1
|
||||||
[out]
|
[/CASE]
|
||||||
|
|
||||||
[CASE mypy_django_ini_in_current_directory_is_a_default]
|
[CASE mypy_django_ini_in_current_directory_is_a_default]
|
||||||
|
[disable_cache]
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
reveal_type(settings.MY_SETTING) # E: Revealed type is 'builtins.int'
|
reveal_type(settings.MY_SETTING) # E: Revealed type is 'builtins.int'
|
||||||
|
|
||||||
@@ -32,4 +34,4 @@ django_settings = mysettings
|
|||||||
|
|
||||||
[file mysettings.py]
|
[file mysettings.py]
|
||||||
MY_SETTING: int = 1
|
MY_SETTING: int = 1
|
||||||
[out]
|
[/CASE]
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ class User(models.Model):
|
|||||||
|
|
||||||
user = User()
|
user = User()
|
||||||
reveal_type(user.array) # E: Revealed type is 'builtins.list*[Any]'
|
reveal_type(user.array) # E: Revealed type is 'builtins.list*[Any]'
|
||||||
|
[/CASE]
|
||||||
|
|
||||||
[CASE array_field_base_field_parsed_into_generic_typevar]
|
[CASE array_field_base_field_parsed_into_generic_typevar]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -19,6 +20,7 @@ class User(models.Model):
|
|||||||
user = User()
|
user = User()
|
||||||
reveal_type(user.members) # E: Revealed type is 'builtins.list*[builtins.int]'
|
reveal_type(user.members) # E: Revealed type is 'builtins.list*[builtins.int]'
|
||||||
reveal_type(user.members_as_text) # E: Revealed type is 'builtins.list*[builtins.str]'
|
reveal_type(user.members_as_text) # E: Revealed type is 'builtins.list*[builtins.str]'
|
||||||
|
[/CASE]
|
||||||
|
|
||||||
[CASE test_model_fields_classes_present_as_primitives]
|
[CASE test_model_fields_classes_present_as_primitives]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -36,6 +38,7 @@ reveal_type(user.small_int) # E: Revealed type is 'builtins.int*'
|
|||||||
reveal_type(user.name) # E: Revealed type is 'builtins.str*'
|
reveal_type(user.name) # E: Revealed type is 'builtins.str*'
|
||||||
reveal_type(user.slug) # E: Revealed type is 'builtins.str*'
|
reveal_type(user.slug) # E: Revealed type is 'builtins.str*'
|
||||||
reveal_type(user.text) # E: Revealed type is 'builtins.str*'
|
reveal_type(user.text) # E: Revealed type is 'builtins.str*'
|
||||||
|
[/CASE]
|
||||||
|
|
||||||
[CASE test_model_field_classes_from_existing_locations]
|
[CASE test_model_field_classes_from_existing_locations]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -51,6 +54,7 @@ booking = Booking()
|
|||||||
reveal_type(booking.id) # E: Revealed type is 'builtins.int*'
|
reveal_type(booking.id) # E: Revealed type is 'builtins.int*'
|
||||||
reveal_type(booking.time_range) # E: Revealed type is 'Any'
|
reveal_type(booking.time_range) # E: Revealed type is 'Any'
|
||||||
reveal_type(booking.some_decimal) # E: Revealed type is 'decimal.Decimal*'
|
reveal_type(booking.some_decimal) # E: Revealed type is 'decimal.Decimal*'
|
||||||
|
[/CASE]
|
||||||
|
|
||||||
[CASE test_add_id_field_if_no_primary_key_defined]
|
[CASE test_add_id_field_if_no_primary_key_defined]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -59,6 +63,7 @@ class User(models.Model):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
reveal_type(User().id) # E: Revealed type is 'builtins.int'
|
reveal_type(User().id) # E: Revealed type is 'builtins.int'
|
||||||
|
[/CASE]
|
||||||
|
|
||||||
[CASE test_do_not_add_id_if_field_with_primary_key_True_defined]
|
[CASE test_do_not_add_id_if_field_with_primary_key_True_defined]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -68,7 +73,7 @@ class User(models.Model):
|
|||||||
|
|
||||||
reveal_type(User().my_pk) # E: Revealed type is 'builtins.int*'
|
reveal_type(User().my_pk) # E: Revealed type is 'builtins.int*'
|
||||||
reveal_type(User().id) # E: Revealed type is 'Any'
|
reveal_type(User().id) # E: Revealed type is 'Any'
|
||||||
[out]
|
[/CASE]
|
||||||
|
|
||||||
[CASE test_meta_nested_class_allows_subclassing_in_multiple_inheritance]
|
[CASE test_meta_nested_class_allows_subclassing_in_multiple_inheritance]
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@@ -84,7 +89,7 @@ class Mixin2(models.Model):
|
|||||||
|
|
||||||
class User(Mixin1, Mixin2):
|
class User(Mixin1, Mixin2):
|
||||||
pass
|
pass
|
||||||
[out]
|
[/CASE]
|
||||||
|
|
||||||
[CASE test_inheritance_from_abstract_model_does_not_fail_if_field_with_id_exists]
|
[CASE test_inheritance_from_abstract_model_does_not_fail_if_field_with_id_exists]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -93,7 +98,7 @@ class Abstract(models.Model):
|
|||||||
abstract = True
|
abstract = True
|
||||||
class User(Abstract):
|
class User(Abstract):
|
||||||
id = models.AutoField(primary_key=True)
|
id = models.AutoField(primary_key=True)
|
||||||
[out]
|
[/CASE]
|
||||||
|
|
||||||
[CASE standard_it_from_parent_model_could_be_overridden_with_non_integer_field_in_child_model]
|
[CASE standard_it_from_parent_model_could_be_overridden_with_non_integer_field_in_child_model]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -103,11 +108,11 @@ class ParentModel(models.Model):
|
|||||||
class MyModel(ParentModel):
|
class MyModel(ParentModel):
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
reveal_type(MyModel().id) # E: Revealed type is 'uuid.UUID*'
|
reveal_type(MyModel().id) # E: Revealed type is 'uuid.UUID*'
|
||||||
[out]
|
[/CASE]
|
||||||
|
|
||||||
[CASE blank_for_charfield_is_the_same_as_null]
|
[CASE blank_for_charfield_is_the_same_as_null]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
class MyModel(models.Model):
|
class MyModel(models.Model):
|
||||||
text = models.CharField(max_length=30, blank=True)
|
text = models.CharField(max_length=30, blank=True)
|
||||||
MyModel(text=None)
|
MyModel(text=None)
|
||||||
[out]
|
[/CASE]
|
||||||
|
|||||||
19
test-data/typecheck/forms.test
Normal file
19
test-data/typecheck/forms.test
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[CASE no_incompatible_meta_nested_class_false_positive]
|
||||||
|
from django.db import models
|
||||||
|
from django import forms
|
||||||
|
|
||||||
|
class Article(models.Model):
|
||||||
|
pass
|
||||||
|
class Category(models.Model):
|
||||||
|
pass
|
||||||
|
class ArticleForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Article
|
||||||
|
fields = '__all__'
|
||||||
|
class CategoryForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Category
|
||||||
|
fields = '__all__'
|
||||||
|
class CompositeForm(ArticleForm, CategoryForm):
|
||||||
|
pass
|
||||||
|
[out]
|
||||||
@@ -6,7 +6,7 @@ class User(models.Model):
|
|||||||
age = models.IntegerField()
|
age = models.IntegerField()
|
||||||
|
|
||||||
User.objects.create(name='Max', age=10)
|
User.objects.create(name='Max', age=10)
|
||||||
User.objects.create(age='hello') # E: Incompatible type for "age" of "User" (got "str", expected "Union[int, Combinable, Literal['']]")
|
User.objects.create(age=[]) # E: Incompatible type for "age" of "User" (got "List[Any]", expected "Union[float, int, str, Combinable]")
|
||||||
[out]
|
[out]
|
||||||
|
|
||||||
[CASE model_recognises_parent_attributes]
|
[CASE model_recognises_parent_attributes]
|
||||||
@@ -59,6 +59,6 @@ MyModel.objects.create(id=None)
|
|||||||
|
|
||||||
class MyModel2(models.Model):
|
class MyModel2(models.Model):
|
||||||
id = models.IntegerField(primary_key=True, default=None)
|
id = models.IntegerField(primary_key=True, default=None)
|
||||||
MyModel2(id=None) # E: Incompatible type for "id" of "MyModel2" (got "None", expected "Union[int, Combinable, Literal['']]")
|
MyModel2(id=None) # E: Incompatible type for "id" of "MyModel2" (got "None", expected "Union[float, int, str, Combinable]")
|
||||||
MyModel2.objects.create(id=None) # E: Incompatible type for "id" of "MyModel2" (got "None", expected "Union[int, Combinable, Literal['']]")
|
MyModel2.objects.create(id=None) # E: Incompatible type for "id" of "MyModel2" (got "None", expected "Union[float, int, str, Combinable]")
|
||||||
[out]
|
[out]
|
||||||
@@ -14,9 +14,9 @@ from django.db import models
|
|||||||
class MyUser(models.Model):
|
class MyUser(models.Model):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
age = models.IntegerField()
|
age = models.IntegerField()
|
||||||
user = MyUser(name='hello', age='world')
|
user = MyUser(name='hello', age=[])
|
||||||
[out]
|
[out]
|
||||||
main:6: error: Incompatible type for "age" of "MyUser" (got "str", expected "Union[int, Combinable, Literal['']]")
|
main:6: error: Incompatible type for "age" of "MyUser" (got "List[Any]", expected "Union[float, int, str, Combinable]")
|
||||||
|
|
||||||
[CASE arguments_to_init_combined_from_base_classes]
|
[CASE arguments_to_init_combined_from_base_classes]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -63,7 +63,7 @@ from django.db import models
|
|||||||
|
|
||||||
class MyUser1(models.Model):
|
class MyUser1(models.Model):
|
||||||
mypk = models.IntegerField(primary_key=True)
|
mypk = models.IntegerField(primary_key=True)
|
||||||
user = MyUser1(pk='hello') # E: Incompatible type for "pk" of "MyUser1" (got "str", expected "Union[int, Combinable, Literal['']]")
|
user = MyUser1(pk=[]) # E: Incompatible type for "pk" of "MyUser1" (got "List[Any]", expected "Union[float, int, str, Combinable]")
|
||||||
[out]
|
[out]
|
||||||
|
|
||||||
[CASE can_set_foreign_key_by_its_primary_key]
|
[CASE can_set_foreign_key_by_its_primary_key]
|
||||||
@@ -115,7 +115,7 @@ MyModel(1)
|
|||||||
class MyModel2(models.Model):
|
class MyModel2(models.Model):
|
||||||
name = models.IntegerField()
|
name = models.IntegerField()
|
||||||
MyModel2(1, 12)
|
MyModel2(1, 12)
|
||||||
MyModel2(1, 'Maxim') # E: Incompatible type for "name" of "MyModel2" (got "str", expected "Union[int, Combinable, Literal['']]")
|
MyModel2(1, []) # E: Incompatible type for "name" of "MyModel2" (got "List[Any]", expected "Union[float, int, str, Combinable]")
|
||||||
[out]
|
[out]
|
||||||
|
|
||||||
[CASE arguments_passed_as_dictionary_unpacking_are_not_supported]
|
[CASE arguments_passed_as_dictionary_unpacking_are_not_supported]
|
||||||
|
|||||||
@@ -191,6 +191,8 @@ class Profile(models.Model):
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
class App(models.Model):
|
class App(models.Model):
|
||||||
owner = models.ForeignKey(to='myapp.User', on_delete=models.CASCADE, related_name='apps')
|
owner = models.ForeignKey(to='myapp.User', on_delete=models.CASCADE, related_name='apps')
|
||||||
|
[disable_cache]
|
||||||
|
[/CASE]
|
||||||
|
|
||||||
[CASE many_to_many_field_converts_to_queryset_of_model_type]
|
[CASE many_to_many_field_converts_to_queryset_of_model_type]
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -271,7 +273,17 @@ class Book2(models.Model):
|
|||||||
|
|
||||||
reveal_type(Book2().publisher_id) # E: Revealed type is 'builtins.int'
|
reveal_type(Book2().publisher_id) # E: Revealed type is 'builtins.int'
|
||||||
Book2(publisher_id=1)
|
Book2(publisher_id=1)
|
||||||
Book2(publisher_id='hello') # E: Incompatible type for "publisher_id" of "Book2" (got "str", expected "Union[int, Combinable, Literal[''], None]")
|
Book2(publisher_id=[]) # E: Incompatible type for "publisher_id" of "Book2" (got "List[Any]", expected "Union[float, int, str, Combinable, None]")
|
||||||
Book2.objects.create(publisher_id=1)
|
Book2.objects.create(publisher_id=1)
|
||||||
Book2.objects.create(publisher_id='hello') # E: Incompatible type for "publisher_id" of "Book2" (got "str", expected "Union[int, Combinable, Literal['']]")
|
Book2.objects.create(publisher_id=[]) # E: Incompatible type for "publisher_id" of "Book2" (got "List[Any]", expected "Union[float, int, str, Combinable]")
|
||||||
[out]
|
[out]
|
||||||
|
|
||||||
|
[CASE if_model_is_defined_as_name_of_the_class_look_for_it_in_the_same_file]
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
class Book(models.Model):
|
||||||
|
publisher = models.ForeignKey(to='Publisher', on_delete=models.CASCADE)
|
||||||
|
class Publisher(models.Model):
|
||||||
|
pass
|
||||||
|
reveal_type(Book().publisher) # E: Revealed type is 'main.Publisher*'
|
||||||
|
[out]
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
[CASE test_settings_are_parsed_into_django_conf_settings]
|
[CASE test_settings_are_parsed_into_django_conf_settings]
|
||||||
|
[env DJANGO_SETTINGS_MODULE=mysettings]
|
||||||
|
[disable_cache]
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
reveal_type(settings.ROOT_DIR) # E: Revealed type is 'builtins.str'
|
reveal_type(settings.ROOT_DIR) # E: Revealed type is 'builtins.str'
|
||||||
@@ -6,7 +8,6 @@ reveal_type(settings.APPS_DIR) # E: Revealed type is 'pathlib.Path'
|
|||||||
reveal_type(settings.OBJ) # E: Revealed type is 'django.utils.functional.LazyObject'
|
reveal_type(settings.OBJ) # E: Revealed type is 'django.utils.functional.LazyObject'
|
||||||
reveal_type(settings.NUMBERS) # E: Revealed type is 'builtins.list[builtins.str]'
|
reveal_type(settings.NUMBERS) # E: Revealed type is 'builtins.list[builtins.str]'
|
||||||
reveal_type(settings.DICT) # E: Revealed type is 'builtins.dict[Any, Any]'
|
reveal_type(settings.DICT) # E: Revealed type is 'builtins.dict[Any, Any]'
|
||||||
[env DJANGO_SETTINGS_MODULE=mysettings]
|
|
||||||
[file base.py]
|
[file base.py]
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
ROOT_DIR = '/etc'
|
ROOT_DIR = '/etc'
|
||||||
@@ -18,14 +19,16 @@ NUMBERS = ['one', 'two']
|
|||||||
DICT = {} # type: ignore
|
DICT = {} # type: ignore
|
||||||
from django.utils.functional import LazyObject
|
from django.utils.functional import LazyObject
|
||||||
OBJ = LazyObject()
|
OBJ = LazyObject()
|
||||||
|
[/CASE]
|
||||||
|
|
||||||
[CASE test_settings_could_be_defined_in_different_module_and_imported_with_star]
|
[CASE test_settings_could_be_defined_in_different_module_and_imported_with_star]
|
||||||
|
[env DJANGO_SETTINGS_MODULE=mysettings]
|
||||||
|
[disable_cache]
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
reveal_type(settings.ROOT_DIR) # E: Revealed type is 'pathlib.Path'
|
reveal_type(settings.ROOT_DIR) # E: Revealed type is 'pathlib.Path'
|
||||||
reveal_type(settings.SETUP) # E: Revealed type is 'builtins.int'
|
reveal_type(settings.SETUP) # E: Revealed type is 'builtins.int'
|
||||||
reveal_type(settings.DATABASES) # E: Revealed type is 'builtins.dict[builtins.str, builtins.str]'
|
reveal_type(settings.DATABASES) # E: Revealed type is 'builtins.dict[builtins.str, builtins.str]'
|
||||||
[env DJANGO_SETTINGS_MODULE=mysettings]
|
|
||||||
[file mysettings.py]
|
[file mysettings.py]
|
||||||
from local import *
|
from local import *
|
||||||
DATABASES = {'default': 'mydb'}
|
DATABASES = {'default': 'mydb'}
|
||||||
@@ -36,24 +39,25 @@ SETUP = 3
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
ROOT_DIR = Path(__file__)
|
ROOT_DIR = Path(__file__)
|
||||||
|
[/CASE]
|
||||||
|
|
||||||
[CASE global_settings_are_always_loaded]
|
[CASE global_settings_are_always_loaded]
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
reveal_type(settings.AUTH_USER_MODEL) # E: Revealed type is 'builtins.str'
|
reveal_type(settings.AUTH_USER_MODEL) # E: Revealed type is 'builtins.str'
|
||||||
reveal_type(settings.AUTHENTICATION_BACKENDS) # E: Revealed type is 'builtins.list[builtins.str]'
|
reveal_type(settings.AUTHENTICATION_BACKENDS) # E: Revealed type is 'typing.Sequence[builtins.str]'
|
||||||
[out]
|
[/CASE]
|
||||||
|
|
||||||
[CASE test_circular_dependency_in_settings_works_if_settings_have_annotations]
|
[CASE test_circular_dependency_in_settings_works_if_settings_have_annotations]
|
||||||
|
[env DJANGO_SETTINGS_MODULE=mysettings]
|
||||||
|
[disable_cache]
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
class Class:
|
class Class:
|
||||||
pass
|
pass
|
||||||
reveal_type(settings.MYSETTING) # E: Revealed type is 'builtins.int'
|
reveal_type(settings.MYSETTING) # E: Revealed type is 'builtins.int'
|
||||||
reveal_type(settings.REGISTRY) # E: Revealed type is 'Union[main.Class, None]'
|
reveal_type(settings.REGISTRY) # E: Revealed type is 'Union[main.Class, None]'
|
||||||
reveal_type(settings.LIST) # E: Revealed type is 'builtins.list[builtins.str]'
|
reveal_type(settings.LIST) # E: Revealed type is 'builtins.list[builtins.str]'
|
||||||
[out]
|
|
||||||
|
|
||||||
[env DJANGO_SETTINGS_MODULE=mysettings]
|
|
||||||
[file mysettings.py]
|
[file mysettings.py]
|
||||||
from typing import TYPE_CHECKING, Optional, List
|
from typing import TYPE_CHECKING, Optional, List
|
||||||
|
|
||||||
@@ -63,13 +67,16 @@ if TYPE_CHECKING:
|
|||||||
MYSETTING = 1122
|
MYSETTING = 1122
|
||||||
REGISTRY: Optional['Class'] = None
|
REGISTRY: Optional['Class'] = None
|
||||||
LIST: List[str] = ['1', '2']
|
LIST: List[str] = ['1', '2']
|
||||||
|
[/CASE]
|
||||||
|
|
||||||
[CASE fail_if_there_is_no_setting]
|
[CASE fail_if_there_is_no_setting]
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
reveal_type(settings.NOT_EXISTING)
|
reveal_type(settings.NOT_EXISTING)
|
||||||
|
|
||||||
[env DJANGO_SETTINGS_MODULE=mysettings]
|
[env DJANGO_SETTINGS_MODULE=mysettings]
|
||||||
|
[disable_cache]
|
||||||
[file mysettings.py]
|
[file mysettings.py]
|
||||||
[out]
|
[out]
|
||||||
main:2: error: Revealed type is 'Any'
|
main:2: error: Revealed type is 'Any'
|
||||||
main:2: error: "LazySettings" has no attribute "NOT_EXISTING"
|
main:2: error: "LazySettings" has no attribute "NOT_EXISTING"
|
||||||
|
[/CASE]
|
||||||
@@ -11,9 +11,11 @@ reveal_type(get_object_or_404(MyModel.objects.get_queryset())) # E: Revealed ty
|
|||||||
reveal_type(get_list_or_404(MyModel)) # E: Revealed type is 'builtins.list[main.MyModel*]'
|
reveal_type(get_list_or_404(MyModel)) # E: Revealed type is 'builtins.list[main.MyModel*]'
|
||||||
reveal_type(get_list_or_404(MyModel.objects)) # E: Revealed type is 'builtins.list[main.MyModel*]'
|
reveal_type(get_list_or_404(MyModel.objects)) # E: Revealed type is 'builtins.list[main.MyModel*]'
|
||||||
reveal_type(get_list_or_404(MyModel.objects.get_queryset())) # E: Revealed type is 'builtins.list[main.MyModel*]'
|
reveal_type(get_list_or_404(MyModel.objects.get_queryset())) # E: Revealed type is 'builtins.list[main.MyModel*]'
|
||||||
[out]
|
[/CASE]
|
||||||
|
|
||||||
[CASE get_user_model_returns_proper_class]
|
[CASE get_user_model_returns_proper_class]
|
||||||
|
[env DJANGO_SETTINGS_MODULE=mysettings]
|
||||||
|
[disable_cache]
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from myapp.models import MyUser
|
from myapp.models import MyUser
|
||||||
@@ -22,7 +24,6 @@ from django.contrib.auth import get_user_model
|
|||||||
UserModel = get_user_model()
|
UserModel = get_user_model()
|
||||||
reveal_type(UserModel.objects) # E: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyUser]'
|
reveal_type(UserModel.objects) # E: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyUser]'
|
||||||
|
|
||||||
[env DJANGO_SETTINGS_MODULE=mysettings]
|
|
||||||
[file mysettings.py]
|
[file mysettings.py]
|
||||||
INSTALLED_APPS = ('myapp',)
|
INSTALLED_APPS = ('myapp',)
|
||||||
AUTH_USER_MODEL = 'myapp.MyUser'
|
AUTH_USER_MODEL = 'myapp.MyUser'
|
||||||
@@ -32,15 +33,16 @@ AUTH_USER_MODEL = 'myapp.MyUser'
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
class MyUser(models.Model):
|
class MyUser(models.Model):
|
||||||
pass
|
pass
|
||||||
[out]
|
[/CASE]
|
||||||
|
|
||||||
[CASE return_type_model_and_show_error_if_model_not_yet_imported]
|
[CASE return_type_model_and_show_error_if_model_not_yet_imported]
|
||||||
|
[env DJANGO_SETTINGS_MODULE=mysettings]
|
||||||
|
[disable_cache]
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
UserModel = get_user_model()
|
UserModel = get_user_model()
|
||||||
reveal_type(UserModel.objects)
|
reveal_type(UserModel.objects)
|
||||||
|
|
||||||
[env DJANGO_SETTINGS_MODULE=mysettings]
|
|
||||||
[file mysettings.py]
|
[file mysettings.py]
|
||||||
INSTALLED_APPS = ('myapp',)
|
INSTALLED_APPS = ('myapp',)
|
||||||
AUTH_USER_MODEL = 'myapp.MyUser'
|
AUTH_USER_MODEL = 'myapp.MyUser'
|
||||||
@@ -53,4 +55,5 @@ class MyUser(models.Model):
|
|||||||
[out]
|
[out]
|
||||||
main:3: error: "myapp.MyUser" model class is not imported so far. Try to import it (under if TYPE_CHECKING) at the beginning of the current file
|
main:3: error: "myapp.MyUser" model class is not imported so far. Try to import it (under if TYPE_CHECKING) at the beginning of the current file
|
||||||
main:4: error: Revealed type is 'Any'
|
main:4: error: Revealed type is 'Any'
|
||||||
main:4: error: "Type[Model]" has no attribute "objects"
|
main:4: error: "Type[Model]" has no attribute "objects"
|
||||||
|
[/CASE]
|
||||||
|
|||||||
50
test-data/typecheck/transaction.test
Normal file
50
test-data/typecheck/transaction.test
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
[CASE test_transaction_atomic]
|
||||||
|
|
||||||
|
from django.db import transaction
|
||||||
|
|
||||||
|
with transaction.atomic():
|
||||||
|
pass
|
||||||
|
|
||||||
|
with transaction.atomic(using="mydb"):
|
||||||
|
pass
|
||||||
|
|
||||||
|
with transaction.atomic(using="mydb", savepoint=False):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@transaction.atomic()
|
||||||
|
def decorated_func(param1: str, param2: int) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Ensure that the function's type is preserved
|
||||||
|
reveal_type(decorated_func) # E: Revealed type is 'def (param1: builtins.str, param2: builtins.int) -> builtins.bool'
|
||||||
|
|
||||||
|
@transaction.atomic(using="mydb")
|
||||||
|
def decorated_func_using(param1: str, param2: int) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Ensure that the function's type is preserved
|
||||||
|
reveal_type(decorated_func_using) # E: Revealed type is 'def (param1: builtins.str, param2: builtins.int) -> builtins.bool'
|
||||||
|
|
||||||
|
class ClassWithAtomicMethod:
|
||||||
|
# Bare decorator
|
||||||
|
@transaction.atomic
|
||||||
|
def atomic_method1(self, abc: int) -> str:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@transaction.atomic(savepoint=True)
|
||||||
|
def atomic_method2(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@transaction.atomic(using="db", savepoint=True)
|
||||||
|
def atomic_method3(self, myparam: str) -> int:
|
||||||
|
pass
|
||||||
|
|
||||||
|
ClassWithAtomicMethod().atomic_method1("abc") # E: Argument 1 to "atomic_method1" of "ClassWithAtomicMethod" has incompatible type "str"; expected "int"
|
||||||
|
|
||||||
|
# Ensure that the method's type is preserved
|
||||||
|
reveal_type(ClassWithAtomicMethod().atomic_method1) # E: Revealed type is 'def (abc: builtins.int) -> builtins.str'
|
||||||
|
|
||||||
|
# Ensure that the method's type is preserved
|
||||||
|
reveal_type(ClassWithAtomicMethod().atomic_method3) # E: Revealed type is 'def (myparam: builtins.str) -> builtins.int'
|
||||||
|
|
||||||
|
[out]
|
||||||
Reference in New Issue
Block a user