summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCurtis Bucher <cpbucher5@gmail.com>2020-03-23 20:49:46 (GMT)
committerGitHub <noreply@github.com>2020-03-23 20:49:46 (GMT)
commit25e580a73c163f472fdeb5489bebef85da21655c (patch)
treeae7ee5d6817eb0efd91e6fd2db0237071fb05b06
parent8dd1792c680caaf94a00cead82b238238f419172 (diff)
downloadcpython-25e580a73c163f472fdeb5489bebef85da21655c.zip
cpython-25e580a73c163f472fdeb5489bebef85da21655c.tar.gz
cpython-25e580a73c163f472fdeb5489bebef85da21655c.tar.bz2
bpo-36144: Add union operators to WeakKeyDictionary (#19106)
-rw-r--r--Doc/library/weakref.rst3
-rw-r--r--Lib/test/test_weakref.py37
-rw-r--r--Lib/weakref.py19
-rw-r--r--Misc/NEWS.d/next/Library/2020-03-18-14-02-58.bpo-36144.ooyn6Z.rst1
4 files changed, 60 insertions, 0 deletions
diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst
index 8636e76..c10f436 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 63c7255..250ed40 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -1624,6 +1624,43 @@ class MappingTestCase(TestBase):
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 e3c2ce2..759ad6d 100644
--- a/Lib/weakref.py
+++ b/Lib/weakref.py
@@ -488,6 +488,25 @@ class WeakKeyDictionary(_collections_abc.MutableMapping):
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 0000000..262653a
--- /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`.