Skip to content

Commit 9e68819

Browse files
authored
Add support for repeated timestamps and durations to to_dict from_dict (#211)
1 parent 59f5f88 commit 9e68819

File tree

4 files changed

+44
-3
lines changed

4 files changed

+44
-3
lines changed

src/betterproto/__init__.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,15 @@ def to_dict(
961961
output[cased_name] = value
962962
elif field_is_repeated:
963963
# Convert each item.
964-
value = [i.to_dict(casing, include_default_values) for i in value]
964+
cls = self._betterproto.cls_by_field[field_name]
965+
if cls == datetime:
966+
value = [_Timestamp.timestamp_to_json(i) for i in value]
967+
elif cls == timedelta:
968+
value = [_Duration.delta_to_json(i) for i in value]
969+
else:
970+
value = [
971+
i.to_dict(casing, include_default_values) for i in value
972+
]
965973
if value or include_default_values:
966974
output[cased_name] = value
967975
elif (
@@ -1042,8 +1050,18 @@ def from_dict(self: T, value: Dict[str, Any]) -> T:
10421050
v = getattr(self, field_name)
10431051
if isinstance(v, list):
10441052
cls = self._betterproto.cls_by_field[field_name]
1045-
for item in value[key]:
1046-
v.append(cls().from_dict(item))
1053+
if cls == datetime:
1054+
v = [
1055+
datetime.fromisoformat(item.replace("Z", "+00:00"))
1056+
for item in value[key]
1057+
]
1058+
elif cls == timedelta:
1059+
v = [
1060+
timedelta(seconds=float(item[:-1]))
1061+
for item in value[key]
1062+
]
1063+
else:
1064+
v = [cls().from_dict(item) for item in value[key]]
10471065
elif isinstance(v, datetime):
10481066
v = datetime.fromisoformat(value[key].replace("Z", "+00:00"))
10491067
setattr(self, field_name, v)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"times": ["1972-01-01T10:00:20.021Z", "1972-01-01T10:00:20.021Z"],
3+
"durations": ["1.200s", "1.200s"]
4+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
syntax = "proto3";
2+
3+
import "google/protobuf/duration.proto";
4+
import "google/protobuf/timestamp.proto";
5+
6+
7+
message Test {
8+
repeated google.protobuf.Timestamp times = 1;
9+
repeated google.protobuf.Duration durations = 2;
10+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from datetime import datetime, timedelta
2+
3+
from tests.output_betterproto.repeated_duration_timestamp import Test
4+
5+
6+
def test_roundtrip():
7+
message = Test()
8+
message.times = [datetime.now(), datetime.now()]
9+
message.durations = [timedelta(), timedelta()]

0 commit comments

Comments
 (0)