mirror of
https://github.com/davidhalter/django-stubs.git
synced 2026-05-17 13:59:46 +08:00
Make decorator functions transparent to Mypy (#306)
By declaring return type as -> Callable[[_C], _C], Mypy can infer that the decorated function has also the same arguments and return type as the original. View functions are constrained to return HttpResponseBase (or any subclass of it). Also added typecheck test coverage to most of the cases.
This commit is contained in:
@@ -1,13 +1,21 @@
|
||||
from typing import Callable, List, Optional, Set, Union
|
||||
from typing import Callable, List, Optional, Set, Union, TypeVar, overload
|
||||
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME as REDIRECT_FIELD_NAME # noqa: F401
|
||||
from django.http.response import HttpResponseBase
|
||||
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
|
||||
_VIEW = TypeVar("_VIEW", bound=Callable[..., HttpResponseBase])
|
||||
|
||||
def user_passes_test(
|
||||
test_func: Callable, login_url: Optional[str] = ..., redirect_field_name: str = ...
|
||||
) -> Callable: ...
|
||||
def login_required(
|
||||
function: Optional[Callable] = ..., redirect_field_name: str = ..., login_url: Optional[str] = ...
|
||||
) -> Callable: ...
|
||||
test_func: Callable[[AbstractUser], bool], login_url: Optional[str] = ..., redirect_field_name: str = ...
|
||||
) -> Callable[[_VIEW], _VIEW]: ...
|
||||
|
||||
# There are two ways of calling @login_required: @with(arguments) and @bare
|
||||
@overload
|
||||
def login_required(redirect_field_name: str = ..., login_url: Optional[str] = ...) -> Callable[[_VIEW], _VIEW]: ...
|
||||
@overload
|
||||
def login_required(function: _VIEW, redirect_field_name: str = ..., login_url: Optional[str] = ...) -> _VIEW: ...
|
||||
def permission_required(
|
||||
perm: Union[List[str], Set[str], str], login_url: None = ..., raise_exception: bool = ...
|
||||
) -> Callable: ...
|
||||
) -> Callable[[_VIEW], _VIEW]: ...
|
||||
|
||||
@@ -39,4 +39,11 @@ def atomic(using: _C) -> _C: ...
|
||||
# Decorator or context-manager with parameters
|
||||
@overload
|
||||
def atomic(using: Optional[str] = ..., savepoint: bool = ...) -> Atomic: ...
|
||||
def non_atomic_requests(using: Callable = ...) -> Callable: ...
|
||||
|
||||
# Bare decorator
|
||||
@overload
|
||||
def non_atomic_requests(using: _C) -> _C: ...
|
||||
|
||||
# Decorator with arguments
|
||||
@overload
|
||||
def non_atomic_requests(using: Optional[str] = ...) -> Callable[[_C], _C]: ...
|
||||
|
||||
@@ -16,6 +16,7 @@ from typing import (
|
||||
Type,
|
||||
Union,
|
||||
ContextManager,
|
||||
TypeVar,
|
||||
)
|
||||
|
||||
from django.apps.registry import Apps
|
||||
@@ -29,6 +30,7 @@ from django.conf import LazySettings, Settings
|
||||
|
||||
_TestClass = Type[SimpleTestCase]
|
||||
_DecoratedTest = Union[Callable, _TestClass]
|
||||
_C = TypeVar("_C", bound=Callable) # Any callable
|
||||
|
||||
TZ_SUPPORT: bool = ...
|
||||
|
||||
@@ -56,7 +58,7 @@ class TestContextDecorator:
|
||||
def __enter__(self) -> Optional[Apps]: ...
|
||||
def __exit__(self, exc_type: None, exc_value: None, traceback: None) -> None: ...
|
||||
def decorate_class(self, cls: _TestClass) -> _TestClass: ...
|
||||
def decorate_callable(self, func: Callable) -> Callable: ...
|
||||
def decorate_callable(self, func: _C) -> _C: ...
|
||||
def __call__(self, decorated: _DecoratedTest) -> Any: ...
|
||||
|
||||
class override_settings(TestContextDecorator):
|
||||
@@ -146,7 +148,7 @@ def get_unique_databases_and_mirrors() -> Tuple[Dict[_Signature, _TestDatabase],
|
||||
def teardown_databases(
|
||||
old_config: Iterable[Tuple[Any, str, bool]], verbosity: int, parallel: int = ..., keepdb: bool = ...
|
||||
) -> None: ...
|
||||
def require_jinja2(test_func: Callable) -> Callable: ...
|
||||
def require_jinja2(test_func: _C) -> _C: ...
|
||||
@contextmanager
|
||||
def register_lookup(
|
||||
field: Type[RegisterLookupMixin], *lookups: Type[Union[Lookup, Transform]], lookup_name: Optional[str] = ...
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
from typing import Any, Callable, Iterable, Optional, Type, Union
|
||||
from typing import Any, Callable, Iterable, Optional, Type, Union, TypeVar
|
||||
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.views.generic.base import View
|
||||
|
||||
_T = TypeVar("_T", bound=Union[View, Callable]) # Any callable
|
||||
|
||||
class classonlymethod(classmethod): ...
|
||||
|
||||
def method_decorator(decorator: Union[Callable, Iterable[Callable]], name: str = ...) -> Callable: ...
|
||||
def method_decorator(decorator: Union[Callable, Iterable[Callable]], name: str = ...) -> Callable[[_T], _T]: ...
|
||||
def decorator_from_middleware_with_args(middleware_class: type) -> Callable: ...
|
||||
def decorator_from_middleware(middleware_class: type) -> Callable: ...
|
||||
def available_attrs(fn: Any): ...
|
||||
def available_attrs(fn: Callable): ...
|
||||
def make_middleware_decorator(middleware_class: Type[MiddlewareMixin]) -> Callable: ...
|
||||
|
||||
class classproperty:
|
||||
|
||||
Reference in New Issue
Block a user