mirror of https://github.com/zulip/zulip.git
typing: Populate POST and _files with `cast` and `setattr`.
`POST` is an immutable attribute and `_files` is an internal attribute of `HttpRequest`. With type annotations provided by `django-stubs`, mypy stops us from modifying these attributes. This uses `cast` and `setattr` to avoid typing issues. This is a part of django-stubs refactorings. Signed-off-by: Zixuan James Li <p359101898@gmail.com>
This commit is contained in:
parent
27be27560b
commit
a3a0545aac
|
@ -4,7 +4,18 @@ import logging
|
||||||
import urllib
|
import urllib
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Callable, Dict, Optional, Sequence, Set, TypeVar, Union, cast, overload
|
from typing import (
|
||||||
|
TYPE_CHECKING,
|
||||||
|
Callable,
|
||||||
|
Dict,
|
||||||
|
Optional,
|
||||||
|
Sequence,
|
||||||
|
Set,
|
||||||
|
TypeVar,
|
||||||
|
Union,
|
||||||
|
cast,
|
||||||
|
overload,
|
||||||
|
)
|
||||||
|
|
||||||
import django_otp
|
import django_otp
|
||||||
import orjson
|
import orjson
|
||||||
|
@ -62,6 +73,9 @@ if settings.ZILENCER_ENABLED:
|
||||||
get_remote_server_by_uuid,
|
get_remote_server_by_uuid,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from django.http.request import _ImmutableQueryDict
|
||||||
|
|
||||||
rate_limiter_logger = logging.getLogger("zerver.lib.rate_limiter")
|
rate_limiter_logger = logging.getLogger("zerver.lib.rate_limiter")
|
||||||
|
|
||||||
webhook_logger = logging.getLogger("zulip.zerver.webhooks")
|
webhook_logger = logging.getLogger("zulip.zerver.webhooks")
|
||||||
|
@ -719,15 +733,26 @@ def process_as_post(view_func: ViewFuncT) -> ViewFuncT:
|
||||||
if not request.POST:
|
if not request.POST:
|
||||||
# Only take action if POST is empty.
|
# Only take action if POST is empty.
|
||||||
if request.content_type == "multipart/form-data":
|
if request.content_type == "multipart/form-data":
|
||||||
# Note that request._files is just the private attribute that backs the
|
POST, _files = MultiPartParser(
|
||||||
# FILES property, so we are essentially setting request.FILES here. (In
|
|
||||||
# Django 1.5 FILES was still a read-only property.)
|
|
||||||
request.POST, request._files = MultiPartParser(
|
|
||||||
request.META,
|
request.META,
|
||||||
BytesIO(request.body),
|
BytesIO(request.body),
|
||||||
request.upload_handlers,
|
request.upload_handlers,
|
||||||
request.encoding,
|
request.encoding,
|
||||||
).parse()
|
).parse()
|
||||||
|
# request.POST is an immutable QueryDict in most cases, while
|
||||||
|
# MultiPartParser.parse() returns a mutable instance of QueryDict.
|
||||||
|
# This can be fix when https://code.djangoproject.com/ticket/17235
|
||||||
|
# is resolved.
|
||||||
|
# django-stubs makes QueryDict of different mutabilities incompatible
|
||||||
|
# types. There is no way to acknowledge the django-stubs mypy plugin
|
||||||
|
# the change of POST's mutability, so we bypass the check with cast.
|
||||||
|
# See also: https://github.com/typeddjango/django-stubs/pull/925#issue-1206399444
|
||||||
|
POST._mutable = False
|
||||||
|
request.POST = cast("_ImmutableQueryDict", POST)
|
||||||
|
# Note that request._files is just the private attribute that backs the
|
||||||
|
# FILES property, so we are essentially setting request.FILES here. (In
|
||||||
|
# Django 3.2 FILES was still a read-only property.)
|
||||||
|
setattr(request, "_files", _files)
|
||||||
elif request.content_type == "application/x-www-form-urlencoded":
|
elif request.content_type == "application/x-www-form-urlencoded":
|
||||||
request.POST = QueryDict(request.body, encoding=request.encoding)
|
request.POST = QueryDict(request.body, encoding=request.encoding)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue