Skip to content

Commit

Permalink
bpo-40273: Reversible mappingproxy (FH-19513)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZackerySpytz authored May 8, 2020
1 parent db9163c commit 02fa0ea
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Doc/library/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,12 @@ Standard names are defined for the following types:

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

.. describe:: reversed(proxy)

Return a reverse iterator over the keys of the underlying mapping.

.. versionadded:: 3.9


Additional Utility Classes and Functions
----------------------------------------
Expand Down
9 changes: 9 additions & 0 deletions Lib/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@ def test_methods(self):
'__iter__',
'__len__',
'__or__',
'__reversed__',
'__ror__',
'copy',
'get',
Expand Down Expand Up @@ -768,6 +769,14 @@ def test_iterators(self):
self.assertEqual(set(view.values()), set(values))
self.assertEqual(set(view.items()), set(items))

def test_reversed(self):
d = {'a': 1, 'b': 2, 'foo': 0, 'c': 3, 'd': 4}
mp = self.mappingproxy(d)
del d['foo']
r = reversed(mp)
self.assertEqual(list(r), list('dcba'))
self.assertRaises(StopIteration, next, r)

def test_copy(self):
original = {'key1': 27, 'key2': 51, 'key3': 93}
view = self.mappingproxy(original)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:class:`types.MappingProxyType` is now reversible.
9 changes: 9 additions & 0 deletions Objects/descrobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,13 @@ mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_copy);
}

static PyObject *
mappingproxy_reversed(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored))
{
_Py_IDENTIFIER(__reversed__);
return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId___reversed__);
}

/* WARNING: mappingproxy methods must not give access
to the underlying mapping */

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

Expand Down

0 comments on commit 02fa0ea

Please sign in to comment.