diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2022-07-05 18:44:31 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-05 18:44:31 (GMT) |
commit | 552fc9a9acd81694bee2001f68ba155315360cfa (patch) | |
tree | 5201be1ab2805c24cbef03520ba6af9aa533d050 /Lib/test/test_dataclasses.py | |
parent | d49c99f10d66e6c485bde7e35d79dea07f3c90eb (diff) | |
download | cpython-552fc9a9acd81694bee2001f68ba155315360cfa.zip cpython-552fc9a9acd81694bee2001f68ba155315360cfa.tar.gz cpython-552fc9a9acd81694bee2001f68ba155315360cfa.tar.bz2 |
gh-91330: Tests and docs for dataclass descriptor-typed fields (GH-94424) (GH-94576)
Co-authored-by: Erik De Bonte <erikd@microsoft.com>
Co-authored-by: Ćukasz Langa <lukasz@langa.pl>
(cherry picked from commit 5f319308a820f49fec66fc3ade50bbaa9fe2105d)
Diffstat (limited to 'Lib/test/test_dataclasses.py')
-rw-r--r-- | Lib/test/test_dataclasses.py | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 822e730..569f979 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -3229,6 +3229,115 @@ class TestDescriptors(unittest.TestCase): self.assertEqual(D.__set_name__.call_count, 1) + def test_init_calls_set(self): + class D: + pass + + D.__set__ = Mock() + + @dataclass + class C: + i: D = D() + + # Make sure D.__set__ is called. + D.__set__.reset_mock() + c = C(5) + self.assertEqual(D.__set__.call_count, 1) + + def test_getting_field_calls_get(self): + class D: + pass + + D.__set__ = Mock() + D.__get__ = Mock() + + @dataclass + class C: + i: D = D() + + c = C(5) + + # Make sure D.__get__ is called. + D.__get__.reset_mock() + value = c.i + self.assertEqual(D.__get__.call_count, 1) + + def test_setting_field_calls_set(self): + class D: + pass + + D.__set__ = Mock() + + @dataclass + class C: + i: D = D() + + c = C(5) + + # Make sure D.__set__ is called. + D.__set__.reset_mock() + c.i = 10 + self.assertEqual(D.__set__.call_count, 1) + + def test_setting_uninitialized_descriptor_field(self): + class D: + pass + + D.__set__ = Mock() + + @dataclass + class C: + i: D + + # D.__set__ is not called because there's no D instance to call it on + D.__set__.reset_mock() + c = C(5) + self.assertEqual(D.__set__.call_count, 0) + + # D.__set__ still isn't called after setting i to an instance of D + # because descriptors don't behave like that when stored as instance vars + c.i = D() + c.i = 5 + self.assertEqual(D.__set__.call_count, 0) + + def test_default_value(self): + class D: + def __get__(self, instance: Any, owner: object) -> int: + if instance is None: + return 100 + + return instance._x + + def __set__(self, instance: Any, value: int) -> None: + instance._x = value + + @dataclass + class C: + i: D = D() + + c = C() + self.assertEqual(c.i, 100) + + c = C(5) + self.assertEqual(c.i, 5) + + def test_no_default_value(self): + class D: + def __get__(self, instance: Any, owner: object) -> int: + if instance is None: + raise AttributeError() + + return instance._x + + def __set__(self, instance: Any, value: int) -> None: + instance._x = value + + @dataclass + class C: + i: D = D() + + with self.assertRaisesRegex(TypeError, 'missing 1 required positional argument'): + c = C() class TestStringAnnotations(unittest.TestCase): def test_classvar(self): |