Skip to content

Commit 8f1ed21

Browse files
authored
bpo-36144: Add union operators to WeakValueDictionary584 (#19127)
1 parent 37fcbb6 commit 8f1ed21

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

Doc/library/weakref.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ than needed.
200200
by the program during iteration may cause items in the dictionary to vanish "by
201201
magic" (as a side effect of garbage collection).
202202

203+
.. versionchanged:: 3.9
204+
Added support for ``|`` and ``|=`` operators, as specified in :pep:`584`.
205+
203206
:class:`WeakValueDictionary` objects have an additional method that has the
204207
same issues as the :meth:`keyrefs` method of :class:`WeakKeyDictionary`
205208
objects.

Lib/test/test_weakref.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,43 @@ def test_weak_valued_dict_update(self):
16091609
self.assertEqual(list(d.keys()), [kw])
16101610
self.assertEqual(d[kw], o)
16111611

1612+
def test_weak_valued_union_operators(self):
1613+
a = C()
1614+
b = C()
1615+
c = C()
1616+
wvd1 = weakref.WeakValueDictionary({1: a})
1617+
wvd2 = weakref.WeakValueDictionary({1: b, 2: a})
1618+
wvd3 = wvd1.copy()
1619+
d1 = {1: c, 3: b}
1620+
pairs = [(5, c), (6, b)]
1621+
1622+
tmp1 = wvd1 | wvd2 # Between two WeakValueDictionaries
1623+
self.assertEqual(dict(tmp1), dict(wvd1) | dict(wvd2))
1624+
self.assertIs(type(tmp1), weakref.WeakValueDictionary)
1625+
wvd1 |= wvd2
1626+
self.assertEqual(wvd1, tmp1)
1627+
1628+
tmp2 = wvd2 | d1 # Between WeakValueDictionary and mapping
1629+
self.assertEqual(dict(tmp2), dict(wvd2) | d1)
1630+
self.assertIs(type(tmp2), weakref.WeakValueDictionary)
1631+
wvd2 |= d1
1632+
self.assertEqual(wvd2, tmp2)
1633+
1634+
tmp3 = wvd3.copy() # Between WeakValueDictionary and iterable key, value
1635+
tmp3 |= pairs
1636+
self.assertEqual(dict(tmp3), dict(wvd3) | dict(pairs))
1637+
self.assertIs(type(tmp3), weakref.WeakValueDictionary)
1638+
1639+
tmp4 = d1 | wvd3 # Testing .__ror__
1640+
self.assertEqual(dict(tmp4), d1 | dict(wvd3))
1641+
self.assertIs(type(tmp4), weakref.WeakValueDictionary)
1642+
1643+
del a
1644+
self.assertNotIn(2, tmp1)
1645+
self.assertNotIn(2, tmp2)
1646+
self.assertNotIn(1, tmp3)
1647+
self.assertNotIn(1, tmp4)
1648+
16121649
def test_weak_keyed_dict_update(self):
16131650
self.check_update(weakref.WeakKeyDictionary,
16141651
{C(): 1, C(): 2, C(): 3})

Lib/weakref.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,25 @@ def valuerefs(self):
310310
self._commit_removals()
311311
return list(self.data.values())
312312

313+
def __ior__(self, other):
314+
self.update(other)
315+
return self
316+
317+
def __or__(self, other):
318+
if isinstance(other, _collections_abc.Mapping):
319+
c = self.copy()
320+
c.update(other)
321+
return c
322+
return NotImplemented
323+
324+
def __ror__(self, other):
325+
if isinstance(other, _collections_abc.Mapping):
326+
c = self.__class__()
327+
c.update(other)
328+
c.update(self)
329+
return c
330+
return NotImplemented
331+
313332

314333
class KeyedRef(ref):
315334
"""Specialized reference that includes a key corresponding to the value.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added :pep:`584` operators to :class:`weakref.WeakValueDictionary`.

0 commit comments

Comments
 (0)