From 3b00367fa91bc6da400dc18e4b2d78ea64f43326 Mon Sep 17 00:00:00 2001 From: surister Date: Tue, 25 Feb 2025 09:15:27 +0100 Subject: [PATCH] Make datetime.time json serializable, to string ISO format. --- CHANGES.rst | 1 + src/crate/client/http.py | 4 ++++ tests/client/test_http.py | 13 ++++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index e9e73d94..1d30ea84 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,7 @@ Changes for crate Unreleased ========== +- Make ``datetime.time`` json serializable. 2025/01/30 2.0.0 ================ diff --git a/src/crate/client/http.py b/src/crate/client/http.py index a1251d34..c9d54c36 100644 --- a/src/crate/client/http.py +++ b/src/crate/client/http.py @@ -98,6 +98,8 @@ def json_encoder(obj: t.Any) -> t.Union[int, str]: - Python's `dt.datetime` and `dt.date` types will be serialized to `int` after converting to milliseconds since epoch. + - Python's `dt.time` will be serialized to `str`, following + the ISO format. https://github.com/ijl/orjson#default https://cratedb.com/docs/crate/reference/en/latest/general/ddl/data-types.html#type-timestamp @@ -113,6 +115,8 @@ def json_encoder(obj: t.Any) -> t.Union[int, str]: delta.microseconds / 1000.0 + (delta.seconds + delta.days * 24 * 3600) * 1000.0 ) + if isinstance(obj, dt.time): + return obj.isoformat() if isinstance(obj, dt.date): return calendar.timegm(obj.timetuple()) * 1000 raise TypeError diff --git a/tests/client/test_http.py b/tests/client/test_http.py index c4c0609e..1f0aacf8 100644 --- a/tests/client/test_http.py +++ b/tests/client/test_http.py @@ -18,7 +18,6 @@ # However, if you have executed another commercial license agreement # with Crate these terms will supersede the license and you may use the # software solely pursuant to the terms of the relevant commercial agreement. - import datetime as dt import json import multiprocessing @@ -354,6 +353,18 @@ def test_uuid_serialization(self, request): self.assertEqual(data["args"], [str(uid)]) client.close() + @patch(REQUEST, autospec=True) + def test_time_serialization(self, request): + client = Client(servers="localhost:4200") + request.return_value = fake_response(200) + + obj = dt.datetime.now().time() + client.sql("insert into my_table (str_col) values (?)", (obj,)) + + data = json.loads(request.call_args[1]["data"]) + self.assertEqual(data["args"], [str(obj)]) + client.close() + @patch(REQUEST, fake_request(duplicate_key_exception())) def test_duplicate_key_error(self): """