mirror of https://github.com/python/cpython
bpo-35992: Use PySequence_GetItem only if sq_item is not NULL (GH-11857)
Not using `__class_getitem__()` fallback if there is a non-subcriptable metaclass was caused by a certain asymmetry between how `PySequenceMethods` and `PyMappingMethods` are used in `PyObject_GetItem`. This PR removes this asymmetry. No tests failed, so I assume it was not intentional.
This commit is contained in:
parent
1bf8845f74
commit
ac28147e78
|
@ -248,7 +248,14 @@ class TestClassGetitem(unittest.TestCase):
|
||||||
return f'{cls.__name__}[{item.__name__}]'
|
return f'{cls.__name__}[{item.__name__}]'
|
||||||
self.assertEqual(Meta[int], 'Meta[int]')
|
self.assertEqual(Meta[int], 'Meta[int]')
|
||||||
|
|
||||||
def test_class_getitem_metaclass_2(self):
|
def test_class_getitem_with_metaclass(self):
|
||||||
|
class Meta(type): pass
|
||||||
|
class C(metaclass=Meta):
|
||||||
|
def __class_getitem__(cls, item):
|
||||||
|
return f'{cls.__name__}[{item.__name__}]'
|
||||||
|
self.assertEqual(C[int], 'C[int]')
|
||||||
|
|
||||||
|
def test_class_getitem_metaclass_first(self):
|
||||||
class Meta(type):
|
class Meta(type):
|
||||||
def __getitem__(cls, item):
|
def __getitem__(cls, item):
|
||||||
return 'from metaclass'
|
return 'from metaclass'
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix ``__class_getitem__()`` not being called on a class with a custom
|
||||||
|
non-subscriptable metaclass.
|
|
@ -143,6 +143,7 @@ PyObject *
|
||||||
PyObject_GetItem(PyObject *o, PyObject *key)
|
PyObject_GetItem(PyObject *o, PyObject *key)
|
||||||
{
|
{
|
||||||
PyMappingMethods *m;
|
PyMappingMethods *m;
|
||||||
|
PySequenceMethods *ms;
|
||||||
|
|
||||||
if (o == NULL || key == NULL) {
|
if (o == NULL || key == NULL) {
|
||||||
return null_error();
|
return null_error();
|
||||||
|
@ -155,7 +156,8 @@ PyObject_GetItem(PyObject *o, PyObject *key)
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o->ob_type->tp_as_sequence) {
|
ms = o->ob_type->tp_as_sequence;
|
||||||
|
if (ms && ms->sq_item) {
|
||||||
if (PyIndex_Check(key)) {
|
if (PyIndex_Check(key)) {
|
||||||
Py_ssize_t key_value;
|
Py_ssize_t key_value;
|
||||||
key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
|
key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
|
||||||
|
@ -163,9 +165,10 @@ PyObject_GetItem(PyObject *o, PyObject *key)
|
||||||
return NULL;
|
return NULL;
|
||||||
return PySequence_GetItem(o, key_value);
|
return PySequence_GetItem(o, key_value);
|
||||||
}
|
}
|
||||||
else if (o->ob_type->tp_as_sequence->sq_item)
|
else {
|
||||||
return type_error("sequence index must "
|
return type_error("sequence index must "
|
||||||
"be integer, not '%.200s'", key);
|
"be integer, not '%.200s'", key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyType_Check(o)) {
|
if (PyType_Check(o)) {
|
||||||
|
|
Loading…
Reference in New Issue