@@ -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