[Python-checkins] bpo-35992: Use PySequence_GetItem only if sq_item is not NULL (GH-11857)

Ivan Levkivskyi webhook-mailer at python.org
Sun Feb 17 18:13:56 EST 2019


https://github.com/python/cpython/commit/ac28147e78c45a6217d348ce90ca5281d91f676f
commit: ac28147e78c45a6217d348ce90ca5281d91f676f
branch: master
author: Ivan Levkivskyi <levkivskyi at gmail.com>
committer: GitHub <noreply at github.com>
date: 2019年02月17日T23:13:46Z
summary:
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.
files:
A Misc/NEWS.d/next/Core and Builtins/2019-02-14-12-01-44.bpo-35992.nG9e2L.rst
M Lib/test/test_genericclass.py
M Objects/abstract.c
diff --git a/Lib/test/test_genericclass.py b/Lib/test/test_genericclass.py
index 37e755b1167e..37a87bc6815e 100644
--- a/Lib/test/test_genericclass.py
+++ b/Lib/test/test_genericclass.py
@@ -248,7 +248,14 @@ def __class_getitem__(cls, item):
 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'
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-14-12-01-44.bpo-35992.nG9e2L.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-14-12-01-44.bpo-35992.nG9e2L.rst
new file mode 100644
index 000000000000..3d8dcd48cd0f
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-02-14-12-01-44.bpo-35992.nG9e2L.rst	
@@ -0,0 +1,2 @@
+Fix ``__class_getitem__()`` not being called on a class with a custom
+non-subscriptable metaclass.
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 567da2d6b50c..0565ba34f5b8 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -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)) {


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /