]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40273: Reversible mappingproxy (FH-19513)
authorZackery Spytz <zspytz@gmail.com>
Fri, 8 May 2020 05:25:50 +0000 (23:25 -0600)
committerGitHub <noreply@github.com>
Fri, 8 May 2020 05:25:50 +0000 (22:25 -0700)
Doc/library/types.rst
Lib/test/test_types.py
Misc/NEWS.d/next/Library/2020-04-14-09-54-35.bpo-40273.IN73Ks.rst [new file with mode: 0644]
Objects/descrobject.c

index 4cb91c1a90bcfced6106ae4e1e4b80e55c911dcc..1d081e2c54868d0e01a6f1732276527596a655e2 100644 (file)
@@ -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
 ----------------------------------------
index f42238762ddcca2505dcb30ee8ba259cd6a084b5..28ebfb6e603e368c92383b24a31c0c9177de1605 100644 (file)
@@ -627,6 +627,7 @@ class MappingProxyTests(unittest.TestCase):
              '__iter__',
              '__len__',
              '__or__',
+             '__reversed__',
              '__ror__',
              'copy',
              'get',
@@ -768,6 +769,14 @@ class MappingProxyTests(unittest.TestCase):
         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)
diff --git a/Misc/NEWS.d/next/Library/2020-04-14-09-54-35.bpo-40273.IN73Ks.rst b/Misc/NEWS.d/next/Library/2020-04-14-09-54-35.bpo-40273.IN73Ks.rst
new file mode 100644 (file)
index 0000000..50f547f
--- /dev/null
@@ -0,0 +1 @@
+:class:`types.MappingProxyType` is now reversible.
index c9754a11b89be19a427b25f941141f2d41f69a48..c29cf7a4c44640d6c6f170779df204c1b8a9b27a 100644 (file)
@@ -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 */
 
@@ -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}
 };