bpo-36144: Add PEP 584 operators to collections.ChainMap (#18832) · python/cpython@f393b2c
@@ -232,6 +232,51 @@ def __contains__(self, key):
232232for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
233233self.assertEqual(d.get(k, 100), v)
234234235+def test_union_operators(self):
236+cm1 = ChainMap(dict(a=1, b=2), dict(c=3, d=4))
237+cm2 = ChainMap(dict(a=10, e=5), dict(b=20, d=4))
238+cm3 = cm1.copy()
239+d = dict(a=10, c=30)
240+pairs = [('c', 3), ('p',0)]
241+242+tmp = cm1 | cm2 # testing between chainmaps
243+self.assertEqual(tmp.maps, [cm1.maps[0] | dict(cm2), *cm1.maps[1:]])
244+cm1 |= cm2
245+self.assertEqual(tmp, cm1)
246+247+tmp = cm2 | d # testing between chainmap and mapping
248+self.assertEqual(tmp.maps, [cm2.maps[0] | d, *cm2.maps[1:]])
249+self.assertEqual((d | cm2).maps, [d | dict(cm2)])
250+cm2 |= d
251+self.assertEqual(tmp, cm2)
252+253+# testing behavior between chainmap and iterable key-value pairs
254+with self.assertRaises(TypeError):
255+cm3 | pairs
256+cm3 |= pairs
257+self.assertEqual(cm3.maps, [cm3.maps[0] | dict(pairs), *cm3.maps[1:]])
258+259+# testing proper return types for ChainMap and it's subclasses
260+class Subclass(ChainMap):
261+pass
262+263+class SubclassRor(ChainMap):
264+def __ror__(self, other):
265+return super().__ror__(other)
266+267+tmp = ChainMap() | ChainMap()
268+self.assertIs(type(tmp), ChainMap)
269+self.assertIs(type(tmp.maps[0]), dict)
270+tmp = ChainMap() | Subclass()
271+self.assertIs(type(tmp), ChainMap)
272+self.assertIs(type(tmp.maps[0]), dict)
273+tmp = Subclass() | ChainMap()
274+self.assertIs(type(tmp), Subclass)
275+self.assertIs(type(tmp.maps[0]), dict)
276+tmp = ChainMap() | SubclassRor()
277+self.assertIs(type(tmp), SubclassRor)
278+self.assertIs(type(tmp.maps[0]), dict)
279+235280236281################################################################################
237282### Named Tuples