Skip to content

Commit d42bab9

Browse files
authored
Merge pull request #32 from Marenz/freeze-dispatch
Make `Dispatch` class frozen
2 parents 698de3c + b0e55b8 commit d42bab9

File tree

4 files changed

+36
-18
lines changed

4 files changed

+36
-18
lines changed

RELEASE_NOTES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
## Upgrading
88

9-
<!-- Here goes notes on how to upgrade from previous versions, including deprecations and what they should be replaced with -->
9+
- The `Dispatch` class is now a frozen dataclass, meaning that it is immutable. Modifications can still be done using `replace`: `dispatch = replace(dispatch, start_time=new_start_time)`.
1010

1111
## New Features
1212

src/frequenz/client/dispatch/test/_service.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
Useful for testing.
77
"""
88
import dataclasses
9-
from dataclasses import dataclass
9+
from dataclasses import dataclass, replace
1010
from datetime import datetime, timezone
1111

1212
import grpc
@@ -175,7 +175,10 @@ async def UpdateMicrogridDispatch(
175175
)[:]
176176

177177
dispatch = Dispatch.from_protobuf(pb_dispatch)
178-
dispatch.update_time = datetime.now(tz=timezone.utc)
178+
dispatch = replace(
179+
dispatch,
180+
update_time=datetime.now(tz=timezone.utc),
181+
)
179182

180183
self.dispatches[index] = dispatch
181184

src/frequenz/client/dispatch/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ class TimeIntervalFilter:
244244
"""Filter by end_time < end_to."""
245245

246246

247-
@dataclass(kw_only=True)
247+
@dataclass(kw_only=True, frozen=True)
248248
class Dispatch:
249249
"""Represents a dispatch operation within a microgrid system."""
250250

tests/test_dispatch_client.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,35 @@
33

44
"""Tests for the frequenz.client.dispatch package."""
55

6+
from dataclasses import replace
7+
68
import grpc
79
from pytest import raises
810

911
from frequenz.client.dispatch.test.client import FakeClient, to_create_params
1012
from frequenz.client.dispatch.test.generator import DispatchGenerator
13+
from frequenz.client.dispatch.types import Dispatch
14+
15+
16+
def _update(dispatch: Dispatch, created: Dispatch) -> Dispatch:
17+
"""Update the dispatch.
18+
19+
Updates the id, create_time and update_time of the local dispatch
20+
with the values from the created dispatch.
21+
22+
Args:
23+
dispatch: The local dispatch.
24+
created: The created dispatch.
25+
26+
Returns:
27+
The updated dispatch.
28+
"""
29+
return replace(
30+
dispatch,
31+
id=created.id,
32+
create_time=created.create_time,
33+
update_time=created.update_time,
34+
)
1135

1236

1337
async def test_create_dispatch() -> None:
@@ -22,8 +46,7 @@ async def test_create_dispatch() -> None:
2246

2347
# Before we can compare, we need to set the create_time and update_time
2448
# as they are generated by the (fake) remote point
25-
sample.create_time = stored_dispatches[0].create_time
26-
sample.update_time = stored_dispatches[0].update_time
49+
sample = _update(sample, stored_dispatches[0])
2750

2851
assert len(stored_dispatches) == 1
2952
assert stored_dispatches[0] == sample
@@ -58,9 +81,7 @@ async def test_list_create_dispatches() -> None:
5881
if dispatch is None:
5982
raise AssertionError("Dispatch not found")
6083

61-
sample.id = dispatch.id
62-
sample.create_time = dispatch.create_time
63-
sample.update_time = dispatch.update_time
84+
sample = _update(sample, dispatch)
6485
assert dispatch == sample
6586

6687

@@ -75,9 +96,7 @@ async def test_update_dispatch() -> None:
7596
dispatch = await anext(client.list(microgrid_id=sample.microgrid_id), None)
7697
assert dispatch is not None
7798

78-
sample.id = dispatch.id
79-
sample.create_time = dispatch.create_time
80-
sample.update_time = dispatch.update_time
99+
sample = _update(sample, dispatch)
81100
assert dispatch == sample
82101

83102
await client.update(dispatch.id, {"recurrence.interval": 4})
@@ -95,9 +114,7 @@ async def test_get_dispatch() -> None:
95114
dispatch = await anext(client.list(microgrid_id=sample.microgrid_id), None)
96115
assert dispatch is not None
97116

98-
sample.id = dispatch.id
99-
sample.create_time = dispatch.create_time
100-
sample.update_time = dispatch.update_time
117+
sample = _update(sample, dispatch)
101118
assert dispatch == sample
102119

103120
assert await client.get(dispatch.id) == dispatch
@@ -122,9 +139,7 @@ async def test_delete_dispatch() -> None:
122139
dispatch = await anext(client.list(microgrid_id=sample.microgrid_id), None)
123140
assert dispatch is not None
124141

125-
sample.id = dispatch.id
126-
sample.create_time = dispatch.create_time
127-
sample.update_time = dispatch.update_time
142+
sample = _update(sample, dispatch)
128143
assert dispatch == sample
129144

130145
await client.delete(dispatch.id)

0 commit comments

Comments
 (0)