[Python-checkins] bpo-36144: Add union operators to WeakKeyDictionary (#19106)

Curtis Bucher webhook-mailer at python.org
Mon Mar 23 16:49:54 EDT 2020


https://github.com/python/cpython/commit/25e580a73c163f472fdeb5489bebef85da21655c
commit: 25e580a73c163f472fdeb5489bebef85da21655c
branch: master
author: Curtis Bucher <cpbucher5 at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-03-23T13:49:46-07:00
summary:

bpo-36144: Add union operators to WeakKeyDictionary (#19106)

files:
A Misc/NEWS.d/next/Library/2020-03-18-14-02-58.bpo-36144.ooyn6Z.rst
M Doc/library/weakref.rst
M Lib/test/test_weakref.py
M Lib/weakref.py

diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst
index 8636e76c52a42..c10f436bea4c4 100644
--- a/Doc/library/weakref.rst
+++ b/Doc/library/weakref.rst
@@ -171,6 +171,9 @@ Extension types can easily be made to support weak references; see
       performed 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, specified in :pep:`584`.
+
 :class:`WeakKeyDictionary` objects have an additional method that
 exposes the internal references directly.  The references are not guaranteed to
 be "live" at the time they are used, so the result of calling the references
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 63c725527d5f2..250ed40b20ca5 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -1624,6 +1624,43 @@ def test_weak_keyed_delitem(self):
         self.assertEqual(len(d), 1)
         self.assertEqual(list(d.keys()), [o2])
 
+    def test_weak_keyed_union_operators(self):
+        o1 = C()
+        o2 = C()
+        o3 = C()
+        wkd1 = weakref.WeakKeyDictionary({o1: 1, o2: 2})
+        wkd2 = weakref.WeakKeyDictionary({o3: 3, o1: 4})
+        wkd3 = wkd1.copy()
+        d1 = {o2: '5', o3: '6'}
+        pairs = [(o2, 7), (o3, 8)]
+
+        tmp1 = wkd1 | wkd2 # Between two WeakKeyDictionaries
+        self.assertEqual(dict(tmp1), dict(wkd1) | dict(wkd2))
+        self.assertIs(type(tmp1), weakref.WeakKeyDictionary)
+        wkd1 |= wkd2
+        self.assertEqual(wkd1, tmp1)
+
+        tmp2 = wkd2 | d1 # Between WeakKeyDictionary and mapping
+        self.assertEqual(dict(tmp2), dict(wkd2) | d1)
+        self.assertIs(type(tmp2), weakref.WeakKeyDictionary)
+        wkd2 |= d1
+        self.assertEqual(wkd2, tmp2)
+
+        tmp3 = wkd3.copy() # Between WeakKeyDictionary and iterable key, value
+        tmp3 |= pairs
+        self.assertEqual(dict(tmp3), dict(wkd3) | dict(pairs))
+        self.assertIs(type(tmp3), weakref.WeakKeyDictionary)
+
+        tmp4 = d1 | wkd3 # Testing .__ror__
+        self.assertEqual(dict(tmp4), d1 | dict(wkd3))
+        self.assertIs(type(tmp4), weakref.WeakKeyDictionary)
+
+        del o1
+        self.assertNotIn(4, tmp1.values())
+        self.assertNotIn(4, tmp2.values())
+        self.assertNotIn(1, tmp3.values())
+        self.assertNotIn(1, tmp4.values())
+
     def test_weak_valued_delitem(self):
         d = weakref.WeakValueDictionary()
         o1 = Object('1')
diff --git a/Lib/weakref.py b/Lib/weakref.py
index e3c2ce2d9b8b8..759ad6dfa39b4 100644
--- a/Lib/weakref.py
+++ b/Lib/weakref.py
@@ -488,6 +488,25 @@ def update(self, dict=None, /, **kwargs):
         if len(kwargs):
             self.update(kwargs)
 
+    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 finalize:
     """Class for finalization of weakrefable objects
diff --git a/Misc/NEWS.d/next/Library/2020-03-18-14-02-58.bpo-36144.ooyn6Z.rst b/Misc/NEWS.d/next/Library/2020-03-18-14-02-58.bpo-36144.ooyn6Z.rst
new file mode 100644
index 0000000000000..262653a01b923
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-03-18-14-02-58.bpo-36144.ooyn6Z.rst
@@ -0,0 +1 @@
+Added :pep:`584` operators to :class:`weakref.WeakKeyDictionary`.



More information about the Python-checkins mailing list