Skip to content

Commit 6852962

Browse files
πŸš‘ Fix embed timestamp JSON serialization (#85)
1 parent 15fe78e commit 6852962

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

β€Žnonebot/adapters/discord/utils.pyβ€Ž

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import date, datetime, time
12
from typing import Any
23
import zlib
34

@@ -22,6 +23,20 @@ def omit_unset(data: Any) -> Any: # noqa: ANN401
2223
return data
2324

2425

26+
def _serialize_datetime_values(data: Any) -> Any: # noqa: ANN401
27+
"""Recursively convert datetime-like values into JSON-safe strings."""
28+
29+
if isinstance(data, dict):
30+
return data.__class__(
31+
(k, _serialize_datetime_values(v)) for k, v in data.items()
32+
)
33+
if isinstance(data, list | tuple | set):
34+
return data.__class__(_serialize_datetime_values(i) for i in data)
35+
if isinstance(data, datetime | date | time):
36+
return data.isoformat()
37+
return data
38+
39+
2540
def model_dump( # noqa: PLR0913
2641
model: BaseModel,
2742
include: set[str] | None = None,
@@ -43,8 +58,8 @@ def model_dump( # noqa: PLR0913
4358
exclude_none=exclude_none,
4459
)
4560
if omit_unset_values:
46-
return omit_unset(data)
47-
return data
61+
data = omit_unset(data)
62+
return _serialize_datetime_values(data)
4863

4964

5065
def escape(s: str) -> str:

β€Žtests/test_api_nullability.pyβ€Ž

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import datetime, timezone
12
import json
23

34
from nonebot.adapters.discord.api import (
@@ -7,6 +8,7 @@
78
SelectOption,
89
)
910
from nonebot.adapters.discord.api.model import (
11+
Embed,
1012
ExecuteWebhookParams,
1113
File,
1214
MessageEditParams,
@@ -42,6 +44,16 @@ def test_parse_data_execute_webhook_omits_unset_fields() -> None:
4244
assert payload == {}
4345

4446

47+
def test_parse_data_serializes_embed_timestamp() -> None:
48+
timestamp = datetime(2026, 3, 14, 12, 0, tzinfo=timezone.utc)
49+
payload = parse_data(
50+
{"embeds": [Embed(timestamp=timestamp)]},
51+
MessageSend,
52+
)["json"]
53+
54+
assert payload["embeds"][0]["timestamp"] == timestamp.isoformat()
55+
56+
4557
def test_parse_data_multipart_keeps_null_attachments() -> None:
4658
res = parse_data(
4759
{
@@ -103,6 +115,22 @@ def test_parse_forum_thread_message_without_content() -> None:
103115
assert payload["message"] == {}
104116

105117

118+
def test_parse_forum_thread_message_serializes_embed_timestamp_in_multipart() -> None:
119+
timestamp = datetime(2026, 3, 14, 12, 0, tzinfo=timezone.utc)
120+
res = parse_forum_thread_message(
121+
{
122+
"name": "thread-name",
123+
"files": [File(content=b"1", filename="a.txt")],
124+
"embeds": [Embed(timestamp=timestamp)],
125+
}
126+
)
127+
multipart = res["files"]
128+
_, payload_json, _ = multipart["payload_json"]
129+
payload = json.loads(payload_json)
130+
131+
assert payload["message"]["embeds"][0]["timestamp"] == timestamp.isoformat()
132+
133+
106134
def test_parse_forum_thread_message_maps_message_attachment_id() -> None:
107135
res = parse_forum_thread_message(
108136
{

0 commit comments

Comments
Β (0)