bpo-43977: Use tp_flags for collection matching (GH-25723)
* Add Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING, add to all relevant standard builtin classes.
* Set relevant flags on collections.abc.Sequence and Mapping.
* Use flags in MATCH_SEQUENCE and MATCH_MAPPING opcodes.
* Inherit Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING.
* Add NEWS
* Remove interpreter-state map_abc and seq_abc fields.
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index dd41620..57a9607 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -1852,7 +1852,8 @@ PyTypeObject PyDictProxy_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_MAPPING, /* tp_flags */
0, /* tp_doc */
mappingproxy_traverse, /* tp_traverse */
0, /* tp_clear */
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 0aeee70..9e2c122 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -3553,7 +3553,7 @@ PyTypeObject PyDict_Type = {
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS |
- _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
+ _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_MAPPING, /* tp_flags */
dictionary_doc, /* tp_doc */
dict_traverse, /* tp_traverse */
dict_tp_clear, /* tp_clear */
diff --git a/Objects/listobject.c b/Objects/listobject.c
index e7987a6..6eb7dce 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -3053,7 +3053,7 @@ PyTypeObject PyList_Type = {
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS |
- _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
+ _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_SEQUENCE, /* tp_flags */
list___init____doc__, /* tp_doc */
(traverseproc)list_traverse, /* tp_traverse */
(inquiry)_list_clear, /* tp_clear */
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c
index d328f4d..913d358 100644
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -3287,7 +3287,8 @@ PyTypeObject PyMemoryView_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
&memory_as_buffer, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_SEQUENCE, /* tp_flags */
memoryview__doc__, /* tp_doc */
(traverseproc)memory_traverse, /* tp_traverse */
(inquiry)memory_clear, /* tp_clear */
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
index 530426c..3e05707 100644
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -735,7 +735,7 @@ PyTypeObject PyRange_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_SEQUENCE, /* tp_flags */
range_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 89c393c..6b1ab74 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -918,7 +918,7 @@ PyTypeObject PyTuple_Type = {
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS |
- _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
+ _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_SEQUENCE, /* tp_flags */
tuple_new__doc__, /* tp_doc */
(traverseproc)tupletraverse, /* tp_traverse */
0, /* tp_clear */
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index ac4dc1d..19d619f 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -5717,10 +5717,15 @@ inherit_special(PyTypeObject *type, PyTypeObject *base)
else if (PyType_IsSubtype(base, &PyDict_Type)) {
type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS;
}
-
if (PyType_HasFeature(base, _Py_TPFLAGS_MATCH_SELF)) {
type->tp_flags |= _Py_TPFLAGS_MATCH_SELF;
}
+ if (PyType_HasFeature(base, Py_TPFLAGS_SEQUENCE)) {
+ type->tp_flags |= Py_TPFLAGS_SEQUENCE;
+ }
+ if (PyType_HasFeature(base, Py_TPFLAGS_MAPPING)) {
+ type->tp_flags |= Py_TPFLAGS_MAPPING;
+ }
}
static int