summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
authorCurtis Bucher <cpbucher5@gmail.com>2020-03-23 13:49:46 -0700
committerGitHub <noreply@github.com>2020-03-23 13:49:46 -0700
commit25e580a73c163f472fdeb5489bebef85da21655c (patch)
treeae7ee5d6817eb0efd91e6fd2db0237071fb05b06 /Lib
parent8dd1792c680caaf94a00cead82b238238f419172 (diff)
downloadcpython-git-25e580a73c163f472fdeb5489bebef85da21655c.tar.gz
bpo-36144: Add union operators to WeakKeyDictionary (#19106)
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_weakref.py37
-rw-r--r--Lib/weakref.py19
2 files changed, 56 insertions, 0 deletions
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 63c725527d..250ed40b20 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 e3c2ce2d9b..759ad6dfa3 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