11
class TestMROEntry(unittest.TestCase):
12
def test_mro_entry_signature(self):
16
def __mro_entries__(self, *args, **kwargs):
17
tested.extend([args, kwargs])
20
self.assertEqual(tested, [])
22
self.assertEqual(tested[0], ((B, c),))
23
self.assertEqual(tested[1], {})
25
def test_mro_entry(self):
30
def __mro_entries__(self, bases):
32
return (self.__class__,)
34
self.assertEqual(tested, [])
36
self.assertEqual(tested[-1], (A, c, B))
37
self.assertEqual(D.__bases__, (A, C, B))
38
self.assertEqual(D.__orig_bases__, (A, c, B))
39
self.assertEqual(D.__mro__, (D, A, C, B, object))
42
self.assertEqual(tested[-1], (d,))
43
self.assertEqual(E.__bases__, (D,))
45
def test_mro_entry_none(self):
50
def __mro_entries__(self, bases):
54
self.assertEqual(tested, [])
56
self.assertEqual(tested[-1], (A, c, B))
57
self.assertEqual(D.__bases__, (A, B))
58
self.assertEqual(D.__orig_bases__, (A, c, B))
59
self.assertEqual(D.__mro__, (D, A, B, object))
61
self.assertEqual(tested[-1], (c,))
62
self.assertEqual(E.__bases__, (object,))
63
self.assertEqual(E.__orig_bases__, (c,))
64
self.assertEqual(E.__mro__, (E, object))
66
def test_mro_entry_with_builtins(self):
70
def __mro_entries__(self, bases):
74
self.assertEqual(tested, [])
76
self.assertEqual(tested[-1], (A, c))
77
self.assertEqual(D.__bases__, (A, dict))
78
self.assertEqual(D.__orig_bases__, (A, c))
79
self.assertEqual(D.__mro__, (D, A, dict, object))
81
def test_mro_entry_with_builtins_2(self):
84
def __mro_entries__(self, bases):
88
self.assertEqual(tested, [])
90
self.assertEqual(tested[-1], (c, dict))
91
self.assertEqual(D.__bases__, (C, dict))
92
self.assertEqual(D.__orig_bases__, (c, dict))
93
self.assertEqual(D.__mro__, (D, C, dict, object))
95
def test_mro_entry_errors(self):
97
def __mro_entries__(self, bases, something, other):
100
with self.assertRaises(TypeError):
103
def __mro_entries__(self):
106
with self.assertRaises(TypeError):
109
def test_mro_entry_errors_2(self):
110
class C_not_callable:
111
__mro_entries__ = "Surprise!"
113
with self.assertRaises(TypeError):
116
def __mro_entries__(self):
119
with self.assertRaises(TypeError):
122
def test_mro_entry_metaclass(self):
125
def __new__(mcls, name, bases, ns):
126
meta_args.extend([mcls, name, bases, ns])
127
return super().__new__(mcls, name, bases, ns)
130
def __mro_entries__(self, bases):
133
class D(c, metaclass=Meta):
135
self.assertEqual(meta_args[0], Meta)
136
self.assertEqual(meta_args[1], 'D')
137
self.assertEqual(meta_args[2], (A,))
138
self.assertEqual(meta_args[3]['x'], 1)
139
self.assertEqual(D.__bases__, (A,))
140
self.assertEqual(D.__orig_bases__, (c,))
141
self.assertEqual(D.__mro__, (D, A, object))
142
self.assertEqual(D.__class__, Meta)
144
def test_mro_entry_type_call(self):
147
def __mro_entries__(self, bases):
150
with self.assertRaisesRegex(TypeError,
151
"MRO entry resolution; "
152
"use types.new_class()"):
153
type('Bad', (c,), {})
156
class TestClassGetitem(unittest.TestCase):
158
def test_no_class_getitem(self):
161
if hasattr(sys, "pypy_version_info") and sys.pypy_version_info < (7, 3, 8):
165
with self.assertRaises(err):
170
def test_class_getitem(self):
173
def __class_getitem__(*args, **kwargs):
174
getitem_args.extend([args, kwargs])
177
self.assertEqual(getitem_args[0], (C, (int, str)))
178
self.assertEqual(getitem_args[1], {})
180
def test_class_getitem_format(self):
182
def __class_getitem__(cls, item):
183
return f'C[{item.__name__}]'
184
self.assertEqual(C[int], 'C[int]')
185
self.assertEqual(C[C], 'C[C]')
187
def test_class_getitem_inheritance(self):
189
def __class_getitem__(cls, item):
190
return f'{cls.__name__}[{item.__name__}]'
192
self.assertEqual(D[int], 'D[int]')
193
self.assertEqual(D[D], 'D[D]')
195
def test_class_getitem_inheritance_2(self):
197
def __class_getitem__(cls, item):
198
return 'Should not see this'
200
def __class_getitem__(cls, item):
201
return f'{cls.__name__}[{item.__name__}]'
202
self.assertEqual(D[int], 'D[int]')
203
self.assertEqual(D[D], 'D[D]')
205
def test_class_getitem_classmethod(self):
208
def __class_getitem__(cls, item):
209
return f'{cls.__name__}[{item.__name__}]'
211
self.assertEqual(D[int], 'D[int]')
212
self.assertEqual(D[D], 'D[D]')
214
def test_class_getitem_patched(self):
216
def __init_subclass__(cls):
217
def __class_getitem__(cls, item):
218
return f'{cls.__name__}[{item.__name__}]'
219
cls.__class_getitem__ = classmethod(__class_getitem__)
221
self.assertEqual(D[int], 'D[int]')
222
self.assertEqual(D[D], 'D[D]')
224
def test_class_getitem_with_builtins(self):
228
def __class_getitem__(cls, item):
229
cls.called_with = item
232
self.assertIs(B.called_with, None)
234
self.assertIs(B.called_with, int)
236
def test_class_getitem_errors(self):
238
def __class_getitem__(cls):
240
with self.assertRaises(TypeError):
243
def __class_getitem__(cls, one, two):
245
with self.assertRaises(TypeError):
248
def test_class_getitem_errors_2(self):
250
def __class_getitem__(cls, item):
252
with self.assertRaises(TypeError):
256
e.__class_getitem__ = lambda cls, item: 'This will not work'
257
with self.assertRaises(TypeError):
259
class C_not_callable:
260
__class_getitem__ = "Surprise!"
261
with self.assertRaises(TypeError):
264
def test_class_getitem_metaclass(self):
266
def __class_getitem__(cls, item):
267
return f'{cls.__name__}[{item.__name__}]'
268
self.assertEqual(Meta[int], 'Meta[int]')
270
def test_class_getitem_with_metaclass(self):
271
class Meta(type): pass
272
class C(metaclass=Meta):
273
def __class_getitem__(cls, item):
274
return f'{cls.__name__}[{item.__name__}]'
275
self.assertEqual(C[int], 'C[int]')
277
def test_class_getitem_metaclass_first(self):
279
def __getitem__(cls, item):
280
return 'from metaclass'
281
class C(metaclass=Meta):
282
def __class_getitem__(cls, item):
283
return 'from __class_getitem__'
284
self.assertEqual(C[int], 'from metaclass')
287
if __name__ == '__main__':