from collections.abc import Awaitable, Callable, Iterable
from typing import Protocol, TypeVar

from django.http.request import HttpRequest
from django.http.response import HttpResponseBase
from django.utils.deprecation import MiddlewareMixin
from django.utils.functional import classproperty as classproperty
from django.views.generic.base import View

_T = TypeVar("_T", bound=View | Callable)  # Any callable
_CallableType = TypeVar("_CallableType", bound=Callable)

class classonlymethod(classmethod): ...

def method_decorator(decorator: 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 make_middleware_decorator(middleware_class: type[MiddlewareMixin]) -> Callable: ...

class AsyncGetResponseCallable(Protocol):
    def __call__(self, __request: HttpRequest) -> Awaitable[HttpResponseBase]: ...

def sync_and_async_middleware(func: _CallableType) -> _CallableType: ...
def sync_only_middleware(func: _CallableType) -> _CallableType: ...
def async_only_middleware(func: _CallableType) -> _CallableType: ...
