Browse Source
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.
pull/4912/merge
Ivan Levkivskyi
7 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with
15 additions and
3 deletions
Lib/test/test_genericclass.py
Misc/NEWS.d/next/Core and Builtins/2019-02-14-12-01-44.bpo-35992.nG9e2L.rst
Objects/abstract.c
@ -248,7 +248,14 @@ class TestClassGetitem(unittest.TestCase):
return f ' {cls.__name__}[{item.__name__}] '
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 ) :
def __getitem__ ( cls , item ) :
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 )
{
PyMappingMethods * m ;
PySequenceMethods * ms ;
if ( o = = NULL | | key = = NULL ) {
return null_error ( ) ;
@ -155,7 +156,8 @@ PyObject_GetItem(PyObject *o, PyObject *key)
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 ) ) {
Py_ssize_t key_value ;
key_value = PyNumber_AsSsize_t ( key , PyExc_IndexError ) ;
@ -163,9 +165,10 @@ PyObject_GetItem(PyObject *o, PyObject *key)
return NULL ;
return PySequence_GetItem ( o , key_value ) ;
}
else if ( o - > ob_type - > tp_as_sequence - > sq_item )
else {
return type_error ( " sequence index must "
" be integer, not '%.200s' " , key ) ;
}
}
if ( PyType_Check ( o ) ) {