Skip to content

Commit baad614

Browse files
author
Datata1
committed
pr feedback
1 parent 7b87f60 commit baad614

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

src/codesphere/core/base.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Generic, List, TypeVar
1+
from typing import Any, Generic, List, Literal, TypeVar
22

33
import yaml
44
from pydantic import BaseModel, ConfigDict, RootModel
@@ -67,7 +67,9 @@ def to_yaml(self, *, by_alias: bool = True, exclude_none: bool = False) -> str:
6767
Returns:
6868
YAML string representation of the model.
6969
"""
70-
data = self.to_dict(by_alias=by_alias, exclude_none=exclude_none)
70+
data = self.model_dump(
71+
by_alias=by_alias, exclude_none=exclude_none, mode="json"
72+
)
7173
return yaml.safe_dump(
7274
data, default_flow_style=False, allow_unicode=True, sort_keys=False
7375
)
@@ -86,19 +88,25 @@ def __len__(self):
8688
return len(self.root)
8789

8890
def to_list(
89-
self, *, by_alias: bool = True, exclude_none: bool = False
91+
self,
92+
*,
93+
by_alias: bool = True,
94+
exclude_none: bool = False,
95+
mode: Literal["python", "json"] = "python",
9096
) -> list[dict[str, Any]]:
9197
"""Export all items as a list of dictionaries.
9298
9399
Args:
94100
by_alias: Use camelCase keys (API format) if True, snake_case if False.
95101
exclude_none: Exclude fields with None values if True.
102+
mode: Serialization mode. "python" returns native Python objects,
103+
"json" returns JSON-compatible types (e.g., datetime as ISO string).
96104
97105
Returns:
98106
List of dictionary representations.
99107
"""
100108
return [
101-
item.model_dump(by_alias=by_alias, exclude_none=exclude_none)
109+
item.model_dump(by_alias=by_alias, exclude_none=exclude_none, mode=mode)
102110
for item in self.root
103111
]
104112

@@ -122,7 +130,8 @@ def to_json(
122130
import json
123131

124132
return json.dumps(
125-
self.to_list(by_alias=by_alias, exclude_none=exclude_none), indent=indent
133+
self.to_list(by_alias=by_alias, exclude_none=exclude_none, mode="json"),
134+
indent=indent,
126135
)
127136

128137
def to_yaml(self, *, by_alias: bool = True, exclude_none: bool = False) -> str:
@@ -135,8 +144,8 @@ def to_yaml(self, *, by_alias: bool = True, exclude_none: bool = False) -> str:
135144
Returns:
136145
YAML string representation.
137146
"""
138-
return yaml.dump(
139-
self.to_list(by_alias=by_alias, exclude_none=exclude_none),
147+
return yaml.safe_dump(
148+
self.to_list(by_alias=by_alias, exclude_none=exclude_none, mode="json"),
140149
default_flow_style=False,
141150
allow_unicode=True,
142151
sort_keys=False,

tests/core/test_base.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
from dataclasses import dataclass
3+
from datetime import datetime, timezone
34
from unittest.mock import MagicMock
45

56
import pytest
@@ -319,6 +320,49 @@ class Item(CamelModel):
319320
assert "itemId: 1" in result
320321
assert "itemId: 2" in result
321322

323+
def test_to_json_with_datetime_field(self):
324+
"""to_json should properly serialize datetime fields to ISO format."""
325+
326+
class Item(CamelModel):
327+
item_id: int
328+
created_at: datetime
329+
330+
dt = datetime(2026, 2, 7, 12, 30, 45, tzinfo=timezone.utc)
331+
items = [Item(item_id=1, created_at=dt)]
332+
resource_list = ResourceList[Item](root=items)
333+
result = resource_list.to_json()
334+
335+
parsed = json.loads(result)
336+
assert parsed == [{"itemId": 1, "createdAt": "2026-02-07T12:30:45Z"}]
337+
338+
def test_to_list_mode_json(self):
339+
"""to_list with mode='json' should return JSON-serializable types."""
340+
341+
class Item(CamelModel):
342+
item_id: int
343+
created_at: datetime
344+
345+
dt = datetime(2026, 2, 7, 12, 30, 45, tzinfo=timezone.utc)
346+
items = [Item(item_id=1, created_at=dt)]
347+
resource_list = ResourceList[Item](root=items)
348+
result = resource_list.to_list(mode="json")
349+
350+
assert result == [{"itemId": 1, "createdAt": "2026-02-07T12:30:45Z"}]
351+
352+
def test_to_list_mode_python(self):
353+
"""to_list with mode='python' (default) should return native Python types."""
354+
355+
class Item(CamelModel):
356+
item_id: int
357+
created_at: datetime
358+
359+
dt = datetime(2026, 2, 7, 12, 30, 45, tzinfo=timezone.utc)
360+
items = [Item(item_id=1, created_at=dt)]
361+
resource_list = ResourceList[Item](root=items)
362+
result = resource_list.to_list()
363+
364+
assert result == [{"itemId": 1, "createdAt": dt}]
365+
322366

323367
class TestResourceBase:
324368
def test_initialization_with_http_client(self):

0 commit comments

Comments
 (0)