From f822e3df32ab804d33280cad1268b05c0df60917 Mon Sep 17 00:00:00 2001 From: Pietro Pasotti Date: Wed, 19 Jul 2023 17:06:14 +0200 Subject: [PATCH 1/4] dedup dcbase.replace --- scenario/state.py | 4 +++- tests/test_dcbase.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 tests/test_dcbase.py diff --git a/scenario/state.py b/scenario/state.py index e33c5d21..1aca605e 100644 --- a/scenario/state.py +++ b/scenario/state.py @@ -80,9 +80,11 @@ class StateValidationError(RuntimeError): @dataclasses.dataclass(frozen=True) class _DCBase: def replace(self, *args, **kwargs): - return dataclasses.replace(self, *args, **kwargs) + """Produce a deep copy of this class, with some arguments replaced with new ones.""" + return dataclasses.replace(self.copy(), *args, **kwargs) def copy(self) -> "Self": + """Produce a deep copy of this object.""" return copy.deepcopy(self) diff --git a/tests/test_dcbase.py b/tests/test_dcbase.py new file mode 100644 index 00000000..fd5ff872 --- /dev/null +++ b/tests/test_dcbase.py @@ -0,0 +1,41 @@ +import dataclasses +from typing import Dict, List + +from scenario.state import _DCBase + + +@dataclasses.dataclass(frozen=True) +class Foo(_DCBase): + a: int + b: List[int] + c: Dict[int, List[int]] + + +def test_base_case(): + l = [1, 2] + l1 = [1, 2, 3] + d = {1: l1} + f = Foo(1, l, d) + g = f.replace(a=2) + + assert g.a == 2 + assert g.b == l + assert g.c == d + assert g.c[1] == l1 + + +def test_dedup_on_replace(): + l = [1, 2] + l1 = [1, 2, 3] + d = {1: l1} + f = Foo(1, l, d) + g = f.replace(a=2) + + l.append(3) + l1.append(4) + d[2] = "foobar" + + assert g.a == 2 + assert g.b == [1, 2] + assert g.c == {1: [1, 2, 3]} + assert g.c[1] == [1, 2, 3] From aa1ad7cba71f3a7b90ecd784fccbeebd6a961a95 Mon Sep 17 00:00:00 2001 From: Pietro Pasotti Date: Wed, 19 Jul 2023 17:06:40 +0200 Subject: [PATCH 2/4] vbump --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f9bcc34d..e7e576b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta" [project] name = "ops-scenario" -version = "4.0" +version = "4.0.1" authors = [ { name = "Pietro Pasotti", email = "pietro.pasotti@canonical.com" } From 4c900c896dc508ddb448be60e1e4d968aa9623fd Mon Sep 17 00:00:00 2001 From: Pietro Pasotti Date: Thu, 20 Jul 2023 09:46:15 +0200 Subject: [PATCH 3/4] vbump --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e7e576b0..c67ea911 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta" [project] name = "ops-scenario" -version = "4.0.1" +version = "4.0.2" authors = [ { name = "Pietro Pasotti", email = "pietro.pasotti@canonical.com" } From 7d4208dcbee9df85fa04d6f92d9ceae9876cfde1 Mon Sep 17 00:00:00 2001 From: Pietro Pasotti Date: Thu, 20 Jul 2023 09:47:35 +0200 Subject: [PATCH 4/4] fixed itest --- tests/test_consistency_checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_consistency_checker.py b/tests/test_consistency_checker.py index c5000d44..a1bf26b4 100644 --- a/tests/test_consistency_checker.py +++ b/tests/test_consistency_checker.py @@ -287,7 +287,7 @@ def test_relation_without_endpoint(): assert_consistent( State( - relations=[Relation("foo", relation_id=1), Relation("bar", relation_id=1)] + relations=[Relation("foo", relation_id=1), Relation("bar", relation_id=2)] ), Event("start"), _CharmSpec(