diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 55ffc36ea5b0c7..6bea12bb6bde65 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1151,7 +1151,10 @@ def clear(self): self.maps[0].clear() def __ior__(self, other): - self.maps[0].update(other) + try: + self.maps[0].update(other) + except TypeError: + return NotImplemented return self def __or__(self, other): diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 22595239252814..6b6197d4d85ae5 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -309,6 +309,19 @@ def __ror__(self, other): self.assertIs(type(tmp), SubclassRor) self.assertIs(type(tmp.maps[0]), dict) + def test_ior_fallback(self): + # Verify that __ior__ returns NotImplemented for unrecognized types, + # allowing the other operand to handle the operation via __ror__. + class Rescuer: + def __ror__(self, other): + return "fallback" + + cm = ChainMap() + # This should not raise TypeError. + # Since ChainMap.__ior__ returns NotImplemented, Python calls Rescuer.__ror__, + # and the result ("fallback") is assigned back to 'cm'. + cm |= Rescuer() + self.assertEqual(cm, "fallback") ################################################################################ ### Named Tuples diff --git a/Misc/NEWS.d/next/Library/2025-11-29-22-23-00.gh-issue-142085.7u8i9o.rst b/Misc/NEWS.d/next/Library/2025-11-29-22-23-00.gh-issue-142085.7u8i9o.rst new file mode 100644 index 00000000000000..d931ed6ec51a5b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-11-29-22-23-00.gh-issue-142085.7u8i9o.rst @@ -0,0 +1,2 @@ +Fix :class:`ChainMap.__ior__ ` to return :data:`NotImplemented` +instead of raising :exc:`TypeError` for unsupported types.