diff --git a/homeassistant/helpers/aiohttp_client.py b/homeassistant/helpers/aiohttp_client.py index 2e56698db41..2ef96091d15 100644 --- a/homeassistant/helpers/aiohttp_client.py +++ b/homeassistant/helpers/aiohttp_client.py @@ -14,7 +14,6 @@ from aiohttp import web from aiohttp.hdrs import CONTENT_TYPE, USER_AGENT from aiohttp.web_exceptions import HTTPBadGateway, HTTPGatewayTimeout import async_timeout -import orjson from homeassistant import config_entries from homeassistant.const import EVENT_HOMEASSISTANT_CLOSE, __version__ @@ -23,6 +22,7 @@ from homeassistant.loader import bind_hass from homeassistant.util import ssl as ssl_util from .frame import warn_use +from .json import json_dumps DATA_CONNECTOR = "aiohttp_connector" DATA_CONNECTOR_NOTVERIFY = "aiohttp_connector_notverify" @@ -98,7 +98,7 @@ def _async_create_clientsession( """Create a new ClientSession with kwargs, i.e. for cookies.""" clientsession = aiohttp.ClientSession( connector=_async_get_connector(hass, verify_ssl), - json_serialize=lambda x: orjson.dumps(x).decode("utf-8"), + json_serialize=json_dumps, **kwargs, ) # Prevent packages accidentally overriding our default headers diff --git a/tests/helpers/test_aiohttp_client.py b/tests/helpers/test_aiohttp_client.py index 599b2c6984e..1ffb4267167 100644 --- a/tests/helpers/test_aiohttp_client.py +++ b/tests/helpers/test_aiohttp_client.py @@ -19,6 +19,7 @@ from homeassistant.const import ( ) from homeassistant.core import EVENT_HOMEASSISTANT_CLOSE import homeassistant.helpers.aiohttp_client as client +from homeassistant.util.color import RGBColor from tests.common import MockConfigEntry @@ -215,6 +216,16 @@ async def test_async_aiohttp_proxy_stream_client_err(aioclient_mock, camera_clie assert resp.status == 502 +async def test_sending_named_tuple(hass, aioclient_mock): + """Test sending a named tuple in json.""" + resp = aioclient_mock.post("http://127.0.0.1/rgb", json={"rgb": RGBColor(4, 3, 2)}) + session = client.async_create_clientsession(hass) + resp = await session.post("http://127.0.0.1/rgb", json={"rgb": RGBColor(4, 3, 2)}) + assert resp.status == 200 + await resp.json() == {"rgb": RGBColor(4, 3, 2)} + aioclient_mock.mock_calls[0][2]["rgb"] == RGBColor(4, 3, 2) + + async def test_client_session_immutable_headers(hass): """Test we can't mutate headers.""" session = client.async_get_clientsession(hass) diff --git a/tests/helpers/test_json.py b/tests/helpers/test_json.py index 54c488690fa..1e85338f152 100644 --- a/tests/helpers/test_json.py +++ b/tests/helpers/test_json.py @@ -2,6 +2,7 @@ import datetime import json import time +from typing import NamedTuple import pytest @@ -13,6 +14,7 @@ from homeassistant.helpers.json import ( json_dumps_sorted, ) from homeassistant.util import dt as dt_util +from homeassistant.util.color import RGBColor @pytest.mark.parametrize("encoder", (JSONEncoder, ExtendedJSONEncoder)) @@ -96,3 +98,23 @@ def test_json_dumps_tuple_subclass(): tt = time.struct_time((1999, 3, 17, 32, 44, 55, 2, 76, 0)) assert json_dumps(tt) == "[1999,3,17,32,44,55,2,76,0]" + + +def test_json_dumps_named_tuple_subclass(): + """Test the json dumps a tuple subclass.""" + + class NamedTupleSubclass(NamedTuple): + """A NamedTuple subclass.""" + + name: str + + nts = NamedTupleSubclass("a") + + assert json_dumps(nts) == '["a"]' + + +def test_json_dumps_rgb_color_subclass(): + """Test the json dumps of RGBColor.""" + rgb = RGBColor(4, 2, 1) + + assert json_dumps(rgb) == "[4,2,1]" diff --git a/tests/test_util/aiohttp.py b/tests/test_util/aiohttp.py index 9ed47109210..4ed81a3a577 100644 --- a/tests/test_util/aiohttp.py +++ b/tests/test_util/aiohttp.py @@ -111,7 +111,7 @@ class AiohttpClientMocker: def create_session(self, loop): """Create a ClientSession that is bound to this mocker.""" - session = ClientSession(loop=loop) + session = ClientSession(loop=loop, json_serialize=json_dumps) # Setting directly on `session` will raise deprecation warning object.__setattr__(session, "_request", self.match_request) return session