summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCurtis Bucher <cpbucher5@gmail.com>2020-03-25 01:51:29 (GMT)
committerGitHub <noreply@github.com>2020-03-25 01:51:29 (GMT)
commit8f1ed21ecf57cc8b8095d9d1058af2b9b3ed0413 (patch)
treed74da03f51570b5a14c1e0a718cfdf47eaa6148d
parent37fcbb65d4589fbb5a72153e9338cf8e6495f64f (diff)
downloadcpython-8f1ed21ecf57cc8b8095d9d1058af2b9b3ed0413.zip
cpython-8f1ed21ecf57cc8b8095d9d1058af2b9b3ed0413.tar.gz
cpython-8f1ed21ecf57cc8b8095d9d1058af2b9b3ed0413.tar.bz2
bpo-36144: Add union operators to WeakValueDictionary584 (#19127)
-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-51-41.bpo-36144.lQm_RK.rst1
4 files changed, 60 insertions, 0 deletions
diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst
index c10f436..12eb985 100644
--- a/Doc/library/weakref.rst
+++ b/Doc/library/weakref.rst
@@ -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.
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 250ed40..563507f 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -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})
diff --git a/Lib/weakref.py b/Lib/weakref.py
index 759ad6d..5fa851d 100644
--- a/Lib/weakref.py
+++ b/Lib/weakref.py
@@ -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
index 0000000..daf1101
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-03-18-14-51-41.bpo-36144.lQm_RK.rst
@@ -0,0 +1 @@
+Added :pep:`584` operators to :class:`weakref.WeakValueDictionary`.