> The |= does exactly what it says on the tin. How could it not mutate the left side of the assignment?
The normal way? If the LHS is an integer. |= updates the binding but does not mutate the object.
Nothing requires that |= mutate the LHS let alone do so unconditionally (e.g. it could update the LHS in place as an optimisation iff the refcount indicated that was the only reference, which would optimise the case where you create a local then update it in multiple steps, but would avoid unwittingly updating a parameter in-place).
edit: you might not be understanding what dict.__ior__ is doing:
>>> a = b = {}
>>> c = {1: 2}
>>> b |= c
>>> a
{1: 2}
That is, `a |= b` does not merely desugar to `a = a | b`, dict.__ior__ does a `self.update(other)` internally before updating the binding to its existing value. Which also leads to this fun bit of trivial (most known from list.__iadd__ but "working" just as well here):
>>> t = ({},)
>>> t[0] |= {1: 2}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t
({1: 2},)