bpo-36144: Add union operators to WeakValueDictionary584 (#19127)

This commit is contained in:
Curtis Bucher 2020-03-24 18:51:29 -07:00 committed by GitHub
parent 37fcbb65d4
commit 8f1ed21ecf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 0 deletions

View File

@ -200,6 +200,9 @@ than needed.
by the program during iteration may cause items in the dictionary to vanish "by by the program during iteration may cause items in the dictionary to vanish "by
magic" (as a side effect of garbage collection). 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 :class:`WeakValueDictionary` objects have an additional method that has the
same issues as the :meth:`keyrefs` method of :class:`WeakKeyDictionary` same issues as the :meth:`keyrefs` method of :class:`WeakKeyDictionary`
objects. objects.

View File

@ -1609,6 +1609,43 @@ class MappingTestCase(TestBase):
self.assertEqual(list(d.keys()), [kw]) self.assertEqual(list(d.keys()), [kw])
self.assertEqual(d[kw], o) 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): def test_weak_keyed_dict_update(self):
self.check_update(weakref.WeakKeyDictionary, self.check_update(weakref.WeakKeyDictionary,
{C(): 1, C(): 2, C(): 3}) {C(): 1, C(): 2, C(): 3})

View File

@ -310,6 +310,25 @@ class WeakValueDictionary(_collections_abc.MutableMapping):
self._commit_removals() self._commit_removals()
return list(self.data.values()) 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): class KeyedRef(ref):
"""Specialized reference that includes a key corresponding to the value. """Specialized reference that includes a key corresponding to the value.

View File

@ -0,0 +1 @@
Added :pep:`584` operators to :class:`weakref.WeakValueDictionary`.