@@ -4077,42 +4077,167 @@ class E(D):
40774077 self .assertEqual (e .a , 2 )
40784078 self .assertEqual (C2 .__subclasses__ (), [D ])
40794079
4080- try :
4080+ with self .assertRaisesRegex (TypeError ,
4081+ "cannot delete '__bases__' attribute of immutable type" ):
40814082 del D .__bases__
4082- except (TypeError , AttributeError ):
4083- pass
4084- else :
4085- self .fail ("shouldn't be able to delete .__bases__" )
4086-
4087- try :
4083+ with self .assertRaisesRegex (TypeError , 'can only assign non-empty tuple' ):
40884084 D .__bases__ = ()
4089- except TypeError as msg :
4090- if str (msg ) == "a new-style class can't have only classic bases" :
4091- self .fail ("wrong error message for .__bases__ = ()" )
4092- else :
4093- self .fail ("shouldn't be able to set .__bases__ to ()" )
4094-
4095- try :
4085+ with self .assertRaisesRegex (TypeError , 'can only assign tuple' ):
4086+ D .__bases__ = [C ]
4087+ with self .assertRaisesRegex (TypeError , 'duplicate base class' ):
4088+ D .__bases__ = (C , C )
4089+ with self .assertRaisesRegex (TypeError , 'inheritance cycle' ):
40964090 D .__bases__ = (D ,)
4097- except TypeError :
4098- pass
4099- else :
4100- # actually, we'll have crashed by here...
4101- self .fail ("shouldn't be able to create inheritance cycles" )
4091+ with self .assertRaisesRegex (TypeError , 'inheritance cycle' ):
4092+ D .__bases__ = (E ,)
41024093
4103- try :
4104- D .__bases__ = (C , C )
4105- except TypeError :
4106- pass
4107- else :
4108- self .fail ("didn't detect repeated base classes" )
4094+ class A :
4095+ __slots__ = ()
4096+ def __repr__ (self ):
4097+ return '<A>'
4098+ class A_with_dict :
4099+ __slots__ = ('__dict__' ,)
4100+ def __repr__ (self ):
4101+ return '<A_with_dict>'
4102+ class A_with_dict_weakref :
4103+ def __repr__ (self ):
4104+ return '<A_with_dict_weakref>'
4105+ class A_with_slots :
4106+ __slots__ = ('x' ,)
4107+ def __repr__ (self ):
4108+ return '<A_with_slots>'
4109+ class A_with_slots_dict :
4110+ __slots__ = ('x' , '__dict__' )
4111+ def __repr__ (self ):
4112+ return '<A_with_slots_dict>'
41094113
4110- try :
4111- D .__bases__ = (E ,)
4112- except TypeError :
4113- pass
4114- else :
4115- self .fail ("shouldn't be able to create inheritance cycles" )
4114+ class B :
4115+ __slots__ = ()
4116+ b = B ()
4117+ r = repr (b )
4118+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4119+ B .__bases__ = (int ,)
4120+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4121+ B .__bases__ = (A_with_dict_weakref ,)
4122+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4123+ B .__bases__ = (A_with_dict ,)
4124+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4125+ B .__bases__ = (A_with_slots ,)
4126+ B .__bases__ = (A ,)
4127+ self .assertNotHasAttr (b , '__dict__' )
4128+ self .assertNotHasAttr (b , '__weakref__' )
4129+ self .assertEqual (repr (b ), '<A>' )
4130+ B .__bases__ = (object ,)
4131+ self .assertEqual (repr (b ), r )
4132+
4133+ class B_with_dict_weakref :
4134+ pass
4135+ b = B_with_dict_weakref ()
4136+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4137+ B .__bases__ = (A_with_slots ,)
4138+ B_with_dict_weakref .__bases__ = (A_with_dict_weakref ,)
4139+ self .assertEqual (repr (b ), '<A_with_dict_weakref>' )
4140+ B_with_dict_weakref .__bases__ = (A_with_dict ,)
4141+ self .assertEqual (repr (b ), '<A_with_dict>' )
4142+ B_with_dict_weakref .__bases__ = (A ,)
4143+ self .assertEqual (repr (b ), '<A>' )
4144+ B_with_dict_weakref .__bases__ = (object ,)
4145+
4146+ class B_with_slots :
4147+ __slots__ = ('x' ,)
4148+ b = B_with_slots ()
4149+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4150+ B_with_slots .__bases__ = (A_with_dict_weakref ,)
4151+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4152+ B_with_slots .__bases__ = (A_with_dict ,)
4153+ B_with_slots .__bases__ = (A ,)
4154+ self .assertEqual (repr (b ), '<A>' )
4155+
4156+ class B_with_slots_dict :
4157+ __slots__ = ('x' , '__dict__' )
4158+ b = B_with_slots_dict ()
4159+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4160+ B_with_slots_dict .__bases__ = (A_with_dict_weakref ,)
4161+ B_with_slots_dict .__bases__ = (A_with_dict ,)
4162+ self .assertEqual (repr (b ), '<A_with_dict>' )
4163+ B_with_slots_dict .__bases__ = (A ,)
4164+ self .assertEqual (repr (b ), '<A>' )
4165+
4166+ class B_with_slots_dict_weakref :
4167+ __slots__ = ('x' , '__dict__' , '__weakref__' )
4168+ b = B_with_slots_dict_weakref ()
4169+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4170+ B_with_slots_dict_weakref .__bases__ = (A_with_slots_dict ,)
4171+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4172+ B_with_slots_dict_weakref .__bases__ = (A_with_slots ,)
4173+ B_with_slots_dict_weakref .__bases__ = (A_with_dict_weakref ,)
4174+ self .assertEqual (repr (b ), '<A_with_dict_weakref>' )
4175+ B_with_slots_dict_weakref .__bases__ = (A_with_dict ,)
4176+ self .assertEqual (repr (b ), '<A_with_dict>' )
4177+ B_with_slots_dict_weakref .__bases__ = (A ,)
4178+ self .assertEqual (repr (b ), '<A>' )
4179+
4180+ class C_with_slots (A_with_slots ):
4181+ __slots__ = ()
4182+ c = C_with_slots ()
4183+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4184+ C_with_slots .__bases__ = (A_with_slots_dict ,)
4185+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4186+ C_with_slots .__bases__ = (A_with_dict_weakref ,)
4187+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4188+ C_with_slots .__bases__ = (A_with_dict ,)
4189+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4190+ C_with_slots .__bases__ = (A ,)
4191+ C_with_slots .__bases__ = (A_with_slots ,)
4192+ self .assertEqual (repr (c ), '<A_with_slots>' )
4193+
4194+ class C_with_slots_dict (A_with_slots ):
4195+ pass
4196+ c = C_with_slots_dict ()
4197+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4198+ C_with_slots_dict .__bases__ = (A_with_dict_weakref ,)
4199+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4200+ C_with_slots_dict .__bases__ = (A_with_dict ,)
4201+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4202+ C_with_slots_dict .__bases__ = (A ,)
4203+ C_with_slots_dict .__bases__ = (A_with_slots_dict ,)
4204+ self .assertEqual (repr (c ), '<A_with_slots_dict>' )
4205+ C_with_slots_dict .__bases__ = (A_with_slots ,)
4206+ self .assertEqual (repr (c ), '<A_with_slots>' )
4207+
4208+ class A_int (int ):
4209+ __slots__ = ()
4210+ def __repr__ (self ):
4211+ return '<A_int>'
4212+ class B_int (int ):
4213+ __slots__ = ()
4214+ b = B_int (42 )
4215+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4216+ B_int .__bases__ = (object ,)
4217+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4218+ B_int .__bases__ = (tuple ,)
4219+ with self .assertRaisesRegex (TypeError , 'is not an acceptable base type' ):
4220+ B_int .__bases__ = (bool ,)
4221+ B_int .__bases__ = (A_int ,)
4222+ self .assertEqual (repr (b ), '<A_int>' )
4223+ B_int .__bases__ = (int ,)
4224+ self .assertEqual (repr (b ), '42' )
4225+
4226+ class A_tuple (tuple ):
4227+ __slots__ = ()
4228+ def __repr__ (self ):
4229+ return '<A_tuple>'
4230+ class B_tuple (tuple ):
4231+ __slots__ = ()
4232+ b = B_tuple ((1 , 2 ))
4233+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4234+ B_tuple .__bases__ = (object ,)
4235+ with self .assertRaisesRegex (TypeError , 'layout differs' ):
4236+ B_tuple .__bases__ = (int ,)
4237+ B_tuple .__bases__ = (A_tuple ,)
4238+ self .assertEqual (repr (b ), '<A_tuple>' )
4239+ B_tuple .__bases__ = (tuple ,)
4240+ self .assertEqual (repr (b ), '(1, 2)' )
41164241
41174242 def test_assign_bases_many_subclasses (self ):
41184243 # This is intended to check that typeobject.c:queue_slot_update() can
@@ -4165,26 +4290,14 @@ class C(object):
41654290 class D (C ):
41664291 pass
41674292
4168- try :
4293+ with self . assertRaisesRegex ( TypeError , 'layout differs' ) :
41694294 L .__bases__ = (dict ,)
4170- except TypeError :
4171- pass
4172- else :
4173- self .fail ("shouldn't turn list subclass into dict subclass" )
41744295
4175- try :
4296+ with self . assertRaisesRegex ( TypeError , 'immutable type' ) :
41764297 list .__bases__ = (dict ,)
4177- except TypeError :
4178- pass
4179- else :
4180- self .fail ("shouldn't be able to assign to list.__bases__" )
41814298
4182- try :
4299+ with self . assertRaisesRegex ( TypeError , 'layout differs' ) :
41834300 D .__bases__ = (C , list )
4184- except TypeError :
4185- pass
4186- else :
4187- self .fail ("best_base calculation found wanting" )
41884301
41894302 def test_unsubclassable_types (self ):
41904303 with self .assertRaises (TypeError ):
0 commit comments