bpo-35992: Use PySequence_GetItem only if sq_item is not NULL (GH-11857) · python/cpython@ac28147 (original) (raw)
File tree
3 files changed
lines changed
- Misc/NEWS.d/next/Core and Builtins
3 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -248,7 +248,14 @@ def __class_getitem__(cls, item): | ||
248 | 248 | return f'{cls.__name__}[{item.__name__}]' |
249 | 249 | self.assertEqual(Meta[int], 'Meta[int]') |
250 | 250 | |
251 | -def test_class_getitem_metaclass_2(self): | |
251 | +def test_class_getitem_with_metaclass(self): | |
252 | +class Meta(type): pass | |
253 | +class C(metaclass=Meta): | |
254 | +def __class_getitem__(cls, item): | |
255 | +return f'{cls.__name__}[{item.__name__}]' | |
256 | +self.assertEqual(C[int], 'C[int]') | |
257 | + | |
258 | +def test_class_getitem_metaclass_first(self): | |
252 | 259 | class Meta(type): |
253 | 260 | def __getitem__(cls, item): |
254 | 261 | return 'from metaclass' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
1 | +Fix ``__class_getitem__()`` not being called on a class with a custom | |
2 | +non-subscriptable metaclass. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -143,6 +143,7 @@ PyObject * | ||
143 | 143 | PyObject_GetItem(PyObject *o, PyObject *key) |
144 | 144 | { |
145 | 145 | PyMappingMethods *m; |
146 | +PySequenceMethods *ms; | |
146 | 147 | |
147 | 148 | if (o == NULL | |
148 | 149 | return null_error(); |
@@ -155,17 +156,19 @@ PyObject_GetItem(PyObject *o, PyObject *key) | ||
155 | 156 | return item; |
156 | 157 | } |
157 | 158 | |
158 | -if (o->ob_type->tp_as_sequence) { | |
159 | +ms = o->ob_type->tp_as_sequence; | |
160 | +if (ms && ms->sq_item) { | |
159 | 161 | if (PyIndex_Check(key)) { |
160 | 162 | Py_ssize_t key_value; |
161 | 163 | key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); |
162 | 164 | if (key_value == -1 && PyErr_Occurred()) |
163 | 165 | return NULL; |
164 | 166 | return PySequence_GetItem(o, key_value); |
165 | 167 | } |
166 | -else if (o->ob_type->tp_as_sequence->sq_item) | |
168 | +else { | |
167 | 169 | return type_error("sequence index must " |
168 | 170 | "be integer, not '%.200s'", key); |
171 | + } | |
169 | 172 | } |
170 | 173 | |
171 | 174 | if (PyType_Check(o)) { |