8000 bpo-36144: Add union operators to WeakKeyDictionary (#19106) · python/cpython@25e580a · GitHub
[go: up one dir, main page]

Skip to content

Commit 25e580a

Browse files
authored
bpo-36144: Add union operators to WeakKeyDictionary (#19106)
1 parent 8dd1792 commit 25e580a

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
@@ -171,6 +171,9 @@ Extension types can easily be made to support weak references; see
171171
performed by the program during iteration may cause items in the
172172
dictionary to vanish "by magic" (as a side effect of garbage collection).
173173

174+
.. versionchanged:: 3.9
175+
Added support for ``|`` and ``|=`` operators, specified in :pep:`584`.
176+
174177
:class:`WeakKeyDictionary` objects have an additional method that
175178
exposes the internal references directly. The references are not guaranteed to
176179
be "live" at the time they are used, so the result of calling the references

Lib/test/test_weakref.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,6 +1624,43 @@ def test_weak_keyed_delitem(self):
16241624
self.assertEqual(len(d), 1)
16251625
self.assertEqual(list(d.keys()), [o2])
16261626

1627+
def test_weak_keyed_union_operators(self):
1628+
o1 = C()
1629+
o2 = C()
1630+
o3 = C()
1631+
wkd1 = weakref.WeakKeyDictionary({o1: 1, o2: 2})
1632+
wkd2 = weakref.WeakKeyDictionary({o3: 3, o1: 4})
1633+
wkd3 = wkd1.copy()
1634+
d1 = {o2: '5', o3: '6'}
1635+
pairs = [(o2, 7), (o3, 8)]
1636+
1637+
tmp1 = wkd1 | wkd2 # Between two WeakKeyDictionaries
1638+
self.assertEqual(dict(tmp1), dict(wkd1) | dict(wkd2))
1639+
self.assertIs(type(tmp1), weakref.WeakKeyDictionary)
1640+
wkd1 |= wkd2
1641+
self.assertEqual(wkd1, tmp1)
1642+
1643+
tmp2 = wkd2 | d1 # Between WeakKeyDictionary and mapping
1644+
self.assertEqual(dict(tmp2), dict(wkd2) | d1)
1645+
self.assertIs(type(tmp2), weakref.WeakKeyDictionary)
1646+
wkd2 |= d1
1647+
self.assertEqual(wkd2, tmp2)
1648+
1649+
tmp3 = wkd3.copy() # Between WeakKeyDictionary and iterable key, value
1650+
tmp3 |= pairs
1651+
self.assertEqual(dict(tmp3), dict(wkd3) | dict(pairs))
1652+
self.assertIs(type(tmp3), weakref.WeakKeyDictionary)
1653+
1654+
tmp4 = d1 | wkd3 # Testing .__ror__
1655+
self.assertEqual(dict(tmp4), d1 | dict(wkd3))
1656+
self.assertIs(type(tmp4), weakref.WeakKeyDictionary)
1657+
1658+
del o1
1659+
self.assertNotIn(4, tmp1.values())
1660+
self.assertNotIn(4, tmp2.values())
1661+
self.assertNotIn(1, tmp3.values())
1662+
self.assertNotIn(1, tmp4.values())
1663+
16271664
def test_weak_valued_delitem(self):
16281665
d = weakref.WeakValueDictionary()
16291666
o1 = Object('1')

Lib/weakref.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,25 @@ def update(self, dict=None, /, **kwargs):
488488
if len(kwargs):
489489
self.update(kwargs)
490490

491+
def __ior__(self, other):
492+
self.update(other)
493+
return self
494+
495+
def __or__(self, other):
496+
if isinstance(other, _collections_abc.Mapping):
497+
c = self.copy()
498+
c.update(other)
499+
return c
500+
return NotImplemented
501+
502+
def __ror__(self, other):
503+
if isinstance(other, _collections_abc.Mapping):
504+
c = self.__class__()
505+
c.update(other)
506+
c.update(self)
507+
return c
508+
return NotImplemented
509+
491510

492511
class finalize:
493512
"""Class for finalization of weakrefable objects
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.WeakKeyDictionary`.

0 commit comments

Comments
 (0)
0