From: Eric V. Smith Date: Wed, 23 Feb 2022 05:14:35 +0000 (-0500) Subject: bpo-46757: Add a test to verify dataclass's __post_init__ isn't being automatically... X-Git-Tag: v3.11.0a6~120 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=288af845a32fd2a92e3b49738faf8f2de6a7bf7c;p=thirdparty%2FPython%2Fcpython.git bpo-46757: Add a test to verify dataclass's __post_init__ isn't being automatically added. (GH-31523) --- diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 69e768508300..2f37ecdfca6b 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