@@ -3971,6 +3971,13 @@ class SlotsTest:
39713971
39723972 return SlotsTest
39733973
3974+ def make_frozen ():
3975+ @dataclass (frozen = True , slots = True )
3976+ class SlotsTest :
3977+ pass
3978+
3979+ return SlotsTest
3980+
39743981 def make_with_annotations ():
39753982 @dataclass (slots = True )
39763983 class SlotsTest :
@@ -3996,14 +4003,39 @@ class SlotsTest:
39964003
39974004 return SlotsTest
39984005
3999- for make in (make_simple , make_with_annotations , make_with_annotations_and_method , make_with_forwardref ):
4006+ for make in (make_simple , make_frozen , make_with_annotations , make_with_annotations_and_method , make_with_forwardref ):
40004007 with self .subTest (make = make ):
40014008 C = make ()
40024009 support .gc_collect ()
40034010 candidates = [cls for cls in object .__subclasses__ () if cls .__name__ == 'SlotsTest'
40044011 and cls .__firstlineno__ == make .__code__ .co_firstlineno + 1 ]
40054012 self .assertEqual (candidates , [C ])
40064013
4014+ def test_set_del_attr_reference_new_class (self ):
4015+ @dataclass (frozen = True , slots = True )
4016+ class SetDelAttrTest :
4017+ pass
4018+
4019+ for method_name in ('__setattr__' , '__delattr__' ):
4020+ with self .subTest (method_name = method_name ):
4021+ method = getattr (SetDelAttrTest , method_name )
4022+ cell_idx = method .__code__ .co_freevars .index ('__class__' )
4023+ reference = method .__closure__ [cell_idx ].cell_contents
4024+ self .assertIs (reference , SetDelAttrTest )
4025+
4026+ def test_set_del_attr_do_not_reference_old_class (self ):
4027+ class SetDelAttrTest :
4028+ pass
4029+
4030+ OriginalCls = SetDelAttrTest
4031+ SetDelAttrTest = dataclass (frozen = True , slots = True )(SetDelAttrTest )
4032+
4033+ for method_name in ('__setattr__' , '__delattr__' ):
4034+ with self .subTest (method_name = method_name ):
4035+ method = getattr (SetDelAttrTest , method_name )
4036+ cell_contents = [cell .cell_contents for cell in method .__closure__ ]
4037+ self .assertNotIn (OriginalCls , cell_contents )
4038+
40074039
40084040class TestDescriptors (unittest .TestCase ):
40094041 def test_set_name (self ):
0 commit comments