From e58241acba2321ff99c362f207a2785c291a9b05 Mon Sep 17 00:00:00 2001 From: James Ward Date: Fri, 27 Sep 2024 02:05:25 -0400 Subject: [PATCH] chore: support `JSONRepsonse` `dumps` callable return type `bytes` the `dumps` parameter is used to serialize the `JSONResponse` to text. this is often done with python's built in `json.dumps` but other times via `orjson.dumps` however, to use `orjson.dumps`, you have to ignore the suggested type (`str`) because `orjson.dumps` returns a `bytes` to correct this, the typing for the dumps callable has been switched to be an `AnyStr` so either `bytes` or `str` returning callable can be passed --- sanic/response/convenience.py | 4 ++-- sanic/response/types.py | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sanic/response/convenience.py b/sanic/response/convenience.py index a58e78733c..65f3954aff 100644 --- a/sanic/response/convenience.py +++ b/sanic/response/convenience.py @@ -38,7 +38,7 @@ def json( status: int = 200, headers: Optional[Dict[str, str]] = None, content_type: str = "application/json", - dumps: Optional[Callable[..., str]] = None, + dumps: Optional[Callable[..., AnyStr]] = None, **kwargs: Any, ) -> JSONResponse: """Returns response object with body in json format. @@ -48,7 +48,7 @@ def json( status (int, optional): HTTP response code. Defaults to `200`. headers (Dict[str, str], optional): Custom HTTP headers. Defaults to `None`. content_type (str, optional): The content type (string) of the response. Defaults to `"application/json"`. - dumps (Callable[..., str], optional): A custom json dumps function. Defaults to `None`. + dumps (Callable[..., AnyStr], optional): A custom json dumps function. Defaults to `None`. **kwargs (Any): Remaining arguments that are passed to the json encoder. Returns: diff --git a/sanic/response/types.py b/sanic/response/types.py index 12f48bc70b..ab197c18cc 100644 --- a/sanic/response/types.py +++ b/sanic/response/types.py @@ -59,7 +59,7 @@ def __repr__(self): class_name = self.__class__.__name__ return f"<{class_name}: {self.status} {self.content_type}>" - def _encode_body(self, data: Optional[AnyStr]): + def _encode_body(self, data: Optional[str | bytes]): if data is None: return b"" return data.encode() if hasattr(data, "encode") else data # type: ignore @@ -264,7 +264,7 @@ class JSONResponse(HTTPResponse): status (int, optional): HTTP response number. Defaults to `200`. headers (Optional[Union[Header, Dict[str, str]]], optional): Headers to be returned. Defaults to `None`. content_type (str, optional): Content type to be returned (as a header). Defaults to `"application/json"`. - dumps (Optional[Callable[..., str]], optional): The function to use for json encoding. Defaults to `None`. + dumps (Optional[Callable[..., AnyStr]], optional): The function to use for json encoding. Defaults to `None`. **kwargs (Any, optional): The kwargs to pass to the json encoding function. Defaults to `{}`. """ # noqa: E501 @@ -283,13 +283,15 @@ def __init__( status: int = 200, headers: Optional[Union[Header, Dict[str, str]]] = None, content_type: str = "application/json", - dumps: Optional[Callable[..., str]] = None, + dumps: Optional[Callable[..., AnyStr]] = None, **kwargs: Any, ): self._initialized = False self._body_manually_set = False - self._use_dumps = dumps or BaseHTTPResponse._dumps + self._use_dumps: Callable[..., str | bytes] = ( + dumps or BaseHTTPResponse._dumps + ) self._use_dumps_kwargs = kwargs self._raw_body = body @@ -352,7 +354,7 @@ def body(self, value: Optional[bytes]): def set_body( self, body: Any, - dumps: Optional[Callable[..., str]] = None, + dumps: Optional[Callable[..., AnyStr]] = None, **dumps_kwargs: Any, ) -> None: """Set the response body to the given value, using the given dumps function @@ -363,7 +365,7 @@ def set_body( Args: body (Any): The body to set - dumps (Optional[Callable[..., str]], optional): The function to use for json encoding. Defaults to `None`. + dumps (Optional[Callable[..., AnyStr]], optional): The function to use for json encoding. Defaults to `None`. **dumps_kwargs (Any, optional): The kwargs to pass to the json encoding function. Defaults to `{}`. Examples: