summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorEric V. Smith <ericvsmith@users.noreply.github.com>2022-02-23 05:14:35 (GMT)
committerGitHub <noreply@github.com>2022-02-23 05:14:35 (GMT)
commit288af845a32fd2a92e3b49738faf8f2de6a7bf7c (patch)
tree425c86776135b2f149701699f79200f764775538 /Lib
parent43cf44ddcce6b225f959ea2a53e4817244ca6054 (diff)
downloadcpython-288af845a32fd2a92e3b49738faf8f2de6a7bf7c.zip
cpython-288af845a32fd2a92e3b49738faf8f2de6a7bf7c.tar.gz
cpython-288af845a32fd2a92e3b49738faf8f2de6a7bf7c.tar.bz2
bpo-46757: Add a test to verify dataclass's __post_init__ isn't being automatically added. (GH-31523)
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_dataclasses.py59
1 files changed, 59 insertions, 0 deletions
diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py
index 69e7685..2f37ecd 100644
--- a/Lib/test/test_dataclasses.py
+++ b/Lib/test/test_dataclasses.py
@@ -1016,6 +1016,65 @@ class TestCase(unittest.TestCase):
self.assertEqual((c.x, c.y), (3, 4))
self.assertTrue(C.flag)
+ def test_post_init_not_auto_added(self):
+ # See bpo-46757, which had proposed always adding __post_init__. As
+ # Raymond Hettinger pointed out, that would be a breaking change. So,
+ # add a test to make sure that the current behavior doesn't change.
+
+ @dataclass
+ class A0:
+ pass
+
+ @dataclass
+ class B0:
+ b_called: bool = False
+ def __post_init__(self):
+ self.b_called = True
+
+ @dataclass
+ class C0(A0, B0):
+ c_called: bool = False
+ def __post_init__(self):
+ super().__post_init__()
+ self.c_called = True
+
+ # Since A0 has no __post_init__, and one wasn't automatically added
+ # (because that's the rule: it's never added by @dataclass, it's only
+ # the class author that can add it), then B0.__post_init__ is called.
+ # Verify that.
+ c = C0()
+ self.assertTrue(c.b_called)
+ self.assertTrue(c.c_called)
+
+ ######################################
+ # Now, the same thing, except A1 defines __post_init__.
+ @dataclass
+ class A1:
+ def __post_init__(self):
+ pass
+
+ @dataclass
+ class B1:
+ b_called: bool = False
+ def __post_init__(self):
+ self.b_called = True
+
+ @dataclass
+ class C1(A1, B1):
+ c_called: bool = False
+ def __post_init__(self):
+ super().__post_init__()
+ self.c_called = True
+
+ # This time, B1.__post_init__ isn't being called. This mimics what
+ # would happen if A1.__post_init__ had been automatically added,
+ # instead of manually added as we see here. This test isn't really
+ # needed, but I'm including it just to demonstrate the changed
+ # behavior when A1 does define __post_init__.
+ c = C1()
+ self.assertFalse(c.b_called)
+ self.assertTrue(c.c_called)
+
def test_class_var(self):
# Make sure ClassVars are ignored in __init__, __repr__, etc.
@dataclass