Bug report
Bug description:
Bug Description
The in-place OR operator (|=) implementation in ChainMap.__ior__ currently lacks a type check. It unconditionally calls self.maps[0].update(other).
If other is not a mapping or an iterable of pairs (e.g., a custom object intended to handle the operation via __ror__), dict.update raises a TypeError.
This behavior prevents the Python interpreter from falling back to the reflected operator (__ror__) on the right-hand operand, breaking interoperability with custom objects.
This is inconsistent with ChainMap.__or__ (the | operator), which correctly checks if not isinstance(other, Mapping) and returns NotImplemented, allowing the fallback mechanism to work.
Reproduction Steps
Run the following script (tested on main branch 3.15.0a2+):
import sys
from collections import ChainMap
class Rescuer:
def __ror__(self, other):
return "SUCCESS"
print(f"Python Version: {sys.version.split()[0]}")
cm = ChainMap({'a': 1})
r = Rescuer()
print("Testing: cm |= r")
try:
# This should fallback to Rescuer.__ror__ but currently crashes
cm |= r
print(f"Result: {cm}")
except TypeError as e:
print(f"CRASH: Raised TypeError: {e}")
Actual Behavior
The script crashes with a TypeError, preventing the fallback.
Testing: cm |= r
CRASH: Raised TypeError: 'Rescuer' object is not iterable
Expected Behavior
The script should output Result: SUCCESS.
ChainMap.__ior__ should catch the TypeError (or check for Mapping type) and return NotImplemented when it encounters an unsupported type. This allows Python to attempt the reflected operation (__ror__) on the other operand.
Python Version
3.15.0a2+ (and 3.11)
CPython versions tested on:
3.11, CPython main branch
Operating systems tested on:
Windows
Linked PRs
Bug report
Bug description:
Bug Description
The in-place OR operator (
|=) implementation inChainMap.__ior__currently lacks a type check. It unconditionally callsself.maps[0].update(other).If
otheris not a mapping or an iterable of pairs (e.g., a custom object intended to handle the operation via__ror__),dict.updateraises aTypeError.This behavior prevents the Python interpreter from falling back to the reflected operator (
__ror__) on the right-hand operand, breaking interoperability with custom objects.This is inconsistent with
ChainMap.__or__(the|operator), which correctly checksif not isinstance(other, Mapping)and returnsNotImplemented, allowing the fallback mechanism to work.Reproduction Steps
Run the following script (tested on main branch 3.15.0a2+):
Actual Behavior
The script crashes with a
TypeError, preventing the fallback.Expected Behavior
The script should output
Result: SUCCESS.ChainMap.__ior__ should catch theTypeError(or check forMappingtype) and returnNotImplementedwhen it encounters an unsupported type. This allows Python to attempt the reflected operation (__ror__) on the other operand.Python Version
3.15.0a2+ (and 3.11)
CPython versions tested on:
3.11, CPython main branch
Operating systems tested on:
Windows
Linked PRs
ChainMap.__ior__before tryingother.__ror__#142087