Allow Views to return the more generic HttpResponseBase instead of HttpResponse, to allow returning StreamingHttpResponse (#607)

* Add type hints for the postgres CursorDebugWrapper, expand the BaseCursorDebugWrapper.

* Fix how Optinal gets applied.

* Fix optional handling further.

* Adjust postgres debugcursorwrapper to look more like the implementation.

* Apply review feedback.

* Use the more generic HttpResponseBase when appriopriate.

* Fix failing test and add new test.

* Remove the other test again, it was the wrong location. Add new tests in the correct location.

Co-authored-by: LanDinh <coding+sourcetree@khaleesi.ninja>
This commit is contained in:
LanDinh
2021-05-01 23:33:05 +02:00
committed by GitHub
parent 2a1c86744c
commit 9251520f66
3 changed files with 30 additions and 11 deletions

View File

@@ -1,6 +1,7 @@
from typing import Any, Callable, Dict, List, Optional, Type from typing import Any, Callable, Dict, List, Optional, Type
from django import http from django import http
from django.http.response import HttpResponseBase
class ContextMixin: class ContextMixin:
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: ... def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: ...
@@ -12,9 +13,9 @@ class View:
kwargs: Any = ... kwargs: Any = ...
def __init__(self, **kwargs: Any) -> None: ... def __init__(self, **kwargs: Any) -> None: ...
@classmethod @classmethod
def as_view(cls: Any, **initkwargs: Any) -> Callable[..., http.HttpResponse]: ... def as_view(cls: Any, **initkwargs: Any) -> Callable[..., HttpResponseBase]: ...
def setup(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> None: ... def setup(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> None: ...
def dispatch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ... def dispatch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponseBase: ...
def http_method_not_allowed(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ... def http_method_not_allowed(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
def options(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ... def options(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
@@ -36,9 +37,9 @@ class RedirectView(View):
pattern_name: Optional[str] = ... pattern_name: Optional[str] = ...
query_string: bool = ... query_string: bool = ...
def get_redirect_url(self, *args: Any, **kwargs: Any) -> Optional[str]: ... def get_redirect_url(self, *args: Any, **kwargs: Any) -> Optional[str]: ...
def get(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ... def get(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponseBase: ...
def head(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ... def head(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponseBase: ...
def post(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ... def post(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponseBase: ...
def delete(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ... def delete(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponseBase: ...
def put(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ... def put(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponseBase: ...
def patch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ... def patch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponseBase: ...

View File

@@ -11,10 +11,10 @@
from django.views.generic.base import View from django.views.generic.base import View
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http.response import HttpResponse from django.http.response import HttpResponseBase
from django.http.request import HttpRequest from django.http.request import HttpRequest
class TestView(View): class TestView(View):
@method_decorator(login_required) @method_decorator(login_required)
def dispatch(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: def dispatch(self, request: HttpRequest, *args, **kwargs) -> HttpResponseBase:
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
reveal_type(dispatch) # N: Revealed type is 'def (self: main.TestView, request: django.http.request.HttpRequest, *args: Any, **kwargs: Any) -> django.http.response.HttpResponse' reveal_type(dispatch) # N: Revealed type is 'def (self: main.TestView, request: django.http.request.HttpRequest, *args: Any, **kwargs: Any) -> django.http.response.HttpResponseBase'

View File

@@ -10,3 +10,21 @@
"""Ensure that form can have type AuthenticationForm.""" """Ensure that form can have type AuthenticationForm."""
form.get_user() form.get_user()
return HttpResponseRedirect(self.get_success_url()) return HttpResponseRedirect(self.get_success_url())
- case: dispatch_http_response
main: |
from django.http import HttpResponse
from django.views.generic.base import View
class MyView(View):
def dispatch(self, request, *args, **kwargs) -> HttpResponse:
response: HttpResponse
return response
- case: dispatch_streaming_http_response
main: |
from django.http import StreamingHttpResponse
from django.views.generic.base import View
class MyView(View):
def dispatch(self, request, *args, **kwargs) -> StreamingHttpResponse:
response: StreamingHttpResponse
return response