]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-36144: Add union operators to WeakValueDictionary584 (#19127)
authorCurtis Bucher <cpbucher5@gmail.com>
Wed, 25 Mar 2020 01:51:29 +0000 (18:51 -0700)
committerGitHub <noreply@github.com>
Wed, 25 Mar 2020 01:51:29 +0000 (18:51 -0700)
Doc/library/weakref.rst
Lib/test/test_weakref.py
Lib/weakref.py
Misc/NEWS.d/next/Library/2020-03-18-14-51-41.bpo-36144.lQm_RK.rst [new file with mode: 0644]

index c10f436bea4c4e4e11862d7416b6b88b2d7590ae..12eb985c3443597e5599c5f43c329e93d2ff4e57 100644 (file)
@@ -200,6 +200,9 @@ than needed.
       by the program during iteration may cause items in the dictionary to vanish "by
       magic" (as a side effect of garbage collection).
 
+   .. versionchanged:: 3.9
+      Added support for ``|`` and ``|=`` operators, as specified in :pep:`584`.
+
 :class:`WeakValueDictionary` objects have an additional method that has the
 same issues as the :meth:`keyrefs` method of :class:`WeakKeyDictionary`
 objects.
index 250ed40b20ca5c442338b310419f109fef1fb448..563507fee3d7ea4960c1936ea033de12fcf1679e 100644 (file)
@@ -1609,6 +1609,43 @@ class MappingTestCase(TestBase):
             self.assertEqual(list(d.keys()), [kw])
             self.assertEqual(d[kw], o)
 
+    def test_weak_valued_union_operators(self):
+        a = C()
+        b = C()
+        c = C()
+        wvd1 = weakref.WeakValueDictionary({1: a})
+        wvd2 = weakref.WeakValueDictionary({1: b, 2: a})
+        wvd3 = wvd1.copy()
+        d1 = {1: c, 3: b}
+        pairs = [(5, c), (6, b)]
+
+        tmp1 = wvd1 | wvd2 # Between two WeakValueDictionaries
+        self.assertEqual(dict(tmp1), dict(wvd1) | dict(wvd2))
+        self.assertIs(type(tmp1), weakref.WeakValueDictionary)
+        wvd1 |= wvd2
+        self.assertEqual(wvd1, tmp1)
+
+        tmp2 = wvd2 | d1 # Between WeakValueDictionary and mapping
+        self.assertEqual(dict(tmp2), dict(wvd2) | d1)
+        self.assertIs(type(tmp2), weakref.WeakValueDictionary)
+        wvd2 |= d1
+        self.assertEqual(wvd2, tmp2)
+
+        tmp3 = wvd3.copy() # Between WeakValueDictionary and iterable key, value
+        tmp3 |= pairs
+        self.assertEqual(dict(tmp3), dict(wvd3) | dict(pairs))
+        self.assertIs(type(tmp3), weakref.WeakValueDictionary)
+
+        tmp4 = d1 | wvd3 # Testing .__ror__
+        self.assertEqual(dict(tmp4), d1 | dict(wvd3))
+        self.assertIs(type(tmp4), weakref.WeakValueDictionary)
+
+        del a
+        self.assertNotIn(2, tmp1)
+        self.assertNotIn(2, tmp2)
+        self.assertNotIn(1, tmp3)
+        self.assertNotIn(1, tmp4)
+
     def test_weak_keyed_dict_update(self):
         self.check_update(weakref.WeakKeyDictionary,
                           {C(): 1, C(): 2, C(): 3})
index 759ad6dfa39b4405674b2c21b6626c328f8422c9..5fa851dd6d771cded9eb7d1fac099e99d09c0ed9 100644 (file)
@@ -310,6 +310,25 @@ class WeakValueDictionary(_collections_abc.MutableMapping):
             self._commit_removals()
         return list(self.data.values())
 
+    def __ior__(self, other):
+        self.update(other)
+        return self
+
+    def __or__(self, other):
+        if isinstance(other, _collections_abc.Mapping):
+            c = self.copy()
+            c.update(other)
+            return c
+        return NotImplemented
+
+    def __ror__(self, other):
+        if isinstance(other, _collections_abc.Mapping):
+            c = self.__class__()
+            c.update(other)
+            c.update(self)
+            return c
+        return NotImplemented
+
 
 class KeyedRef(ref):
     """Specialized reference that includes a key corresponding to the value.
diff --git a/Misc/NEWS.d/next/Library/2020-03-18-14-51-41.bpo-36144.lQm_RK.rst b/Misc/NEWS.d/next/Library/2020-03-18-14-51-41.bpo-36144.lQm_RK.rst
new file mode 100644 (file)
index 0000000..daf1101
--- /dev/null
@@ -0,0 +1 @@
+Added :pep:`584` operators to :class:`weakref.WeakValueDictionary`.