]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-119581: Add a test of InitVar with name shadowing (GH-119582) (#119673)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 28 May 2024 17:42:01 +0000 (19:42 +0200)
committerGitHub <noreply@github.com>
Tue, 28 May 2024 17:42:01 +0000 (17:42 +0000)
gh-119581: Add a test of InitVar with name shadowing (GH-119582)
(cherry picked from commit 6ec371223dff4da7719039e271f35a16a5b861c6)

Co-authored-by: Steven Troxler <steven.troxler@gmail.com>
Lib/test/test_dataclasses/__init__.py

index 7c917707d02f0bbc4744c00fa0340897189fad05..c059726e9327e88d82f2f301766d9056a060ee2a 100644 (file)
@@ -1317,6 +1317,29 @@ class TestCase(unittest.TestCase):
         c = C(10, 11, 50, 51)
         self.assertEqual(vars(c), {'x': 21, 'y': 101})
 
+    def test_init_var_name_shadowing(self):
+        # Because dataclasses rely exclusively on `__annotations__` for
+        # handling InitVar and `__annotations__` preserves shadowed definitions,
+        # you can actually shadow an InitVar with a method or property.
+        #
+        # This only works when there is no default value; `dataclasses` uses the
+        # actual name (which will be bound to the shadowing method) for default
+        # values.
+        @dataclass
+        class C:
+            shadowed: InitVar[int]
+            _shadowed: int = field(init=False)
+
+            def __post_init__(self, shadowed):
+                self._shadowed = shadowed * 2
+
+            @property
+            def shadowed(self):
+                return self._shadowed * 3
+
+        c = C(5)
+        self.assertEqual(c.shadowed, 30)
+
     def test_default_factory(self):
         # Test a factory that returns a new list.
         @dataclass