summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_dataclasses.py
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2022-07-05 18:44:31 (GMT)
committerGitHub <noreply@github.com>2022-07-05 18:44:31 (GMT)
commit552fc9a9acd81694bee2001f68ba155315360cfa (patch)
tree5201be1ab2805c24cbef03520ba6af9aa533d050 /Lib/test/test_dataclasses.py
parentd49c99f10d66e6c485bde7e35d79dea07f3c90eb (diff)
downloadcpython-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.py109
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):