mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	bpo-46757: Add a test to verify dataclass's __post_init__ isn't being automatically added. (GH-31523)
This commit is contained in:
		
							parent
							
								
									43cf44ddcc
								
							
						
					
					
						commit
						288af845a3
					
				
					 1 changed files with 59 additions and 0 deletions
				
			
		|  | @ -1016,6 +1016,65 @@ def __post_init__(cls): | ||||||
|         self.assertEqual((c.x, c.y), (3, 4)) |         self.assertEqual((c.x, c.y), (3, 4)) | ||||||
|         self.assertTrue(C.flag) |         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): |     def test_class_var(self): | ||||||
|         # Make sure ClassVars are ignored in __init__, __repr__, etc. |         # Make sure ClassVars are ignored in __init__, __repr__, etc. | ||||||
|         @dataclass |         @dataclass | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Eric V. Smith
						Eric V. Smith