In python, does `@=` act on the left or the right?

It seems obvious to me that vector @= matrix ought to mean vector = matrix @ vector, contrary to the practice with most other binary operators. Unfortunately, any discussion of this is completely omitted from PEP 465; it states only that the @ operator is left-associative, and that the @= operator corresponds to the __imatmul__ function.

Presumably, the override means that numerical libraries can choose this behavior if they like, but that leaves three closely related question:

  • What is the default behavior if __imatmul__ is not explicitly provided, but __matmul__ and __rmatmul__ are?
  • What is the behavior intended by the authors of the PEP?
  • What behavior have numerical libraries such as numpy chosen to implement?

Like any other augmented assignment operator, x @= y is an in-place-if-x-supports-it version of x = x @ y.

x = y @ x might have seemed obvious to you, but I don't think anything other than x = x @ y was ever considered a serious option, and I don't think any major math library has implemented anything like what you expected. sympy.Matrix implements it as x = x @ y (non-mutative, no __imatmul__), and numpy.ndarray says

TypeError: In-place matrix multiplication is not (yet) supported. Use 'a = a @ b' instead of 'a @= b'.

(Checked with NumPy 1.19.5 and 1.21.5).

Note that NumPy defines a useful meaning for "vector @ matrix" operations. NumPy does not force arrays to be 2D, so the most common vector representation in NumPy is a 1D array, not a column vector. A 1D array will behave like a row vector in a "vector @ matrix" operation, though the result will be 1D instead of a row vector.