Skip to content

Commit 02fa0ea

Browse files
authored
bpo-40273: Reversible mappingproxy (FH-19513)
1 parent db9163c commit 02fa0ea

File tree

4 files changed

+25
-0
lines changed

4 files changed

+25
-0
lines changed

Doc/library/types.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,12 @@ Standard names are defined for the following types:
329329

330330
Return a new view of the underlying mapping's values.
331331

332+
.. describe:: reversed(proxy)
333+
334+
Return a reverse iterator over the keys of the underlying mapping.
335+
336+
.. versionadded:: 3.9
337+
332338

333339
Additional Utility Classes and Functions
334340
----------------------------------------

Lib/test/test_types.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ def test_methods(self):
627627
'__iter__',
628628
'__len__',
629629
'__or__',
630+
'__reversed__',
630631
'__ror__',
631632
'copy',
632633
'get',
@@ -768,6 +769,14 @@ def test_iterators(self):
768769
self.assertEqual(set(view.values()), set(values))
769770
self.assertEqual(set(view.items()), set(items))
770771

772+
def test_reversed(self):
773+
d = {'a': 1, 'b': 2, 'foo': 0, 'c': 3, 'd': 4}
774+
mp = self.mappingproxy(d)
775+
del d['foo']
776+
r = reversed(mp)
777+
self.assertEqual(list(r), list('dcba'))
778+
self.assertRaises(StopIteration, next, r)
779+
771780
def test_copy(self):
772781
original = {'key1': 27, 'key2': 51, 'key3': 93}
773782
view = self.mappingproxy(original)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:class:`types.MappingProxyType` is now reversible.

Objects/descrobject.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,13 @@ mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
11181118
return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_copy);
11191119
}
11201120

1121+
static PyObject *
1122+
mappingproxy_reversed(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
1123+
{
1124+
_Py_IDENTIFIER(__reversed__);
1125+
return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId___reversed__);
1126+
}
1127+
11211128
/* WARNING: mappingproxy methods must not give access
11221129
to the underlying mapping */
11231130

@@ -1135,6 +1142,8 @@ static PyMethodDef mappingproxy_methods[] = {
11351142
PyDoc_STR("D.copy() -> a shallow copy of D")},
11361143
{"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS,
11371144
PyDoc_STR("See PEP 585")},
1145+
{"__reversed__", (PyCFunction)mappingproxy_reversed, METH_NOARGS,
1146+
PyDoc_STR("D.__reversed__() -> reverse iterator")},
11381147
{0}
11391148
};
11401149

0 commit comments

Comments
 (0)