Why this restriction on in-place use of binary or operator?

This code snippet works as intended:

import numba
import numpy as np

@numba.njit(fastmath=True)
def f(a, i, n, mask):
  a[i:i+n] = a[i:i+n] | mask

a = np.random.randint(0, 16, size=(9)).astype('uint8')
f(a, 3, 2, 8)

but when I try to use | operator in-place by substituting a[i:i+n] = a[i:i+n] | mask with a[i:i+n] |= mask, I get:

No implementation of function Function(<built-in function ior>) found for signature: 
 >>> ior(array(uint8, 1d, C), int64)

Given that | has the same function signature in a[i:i+n] | mask, is there a fundamental reason why in-place use is not allowed?

I’m not sure about the specific technical reasons in this case, since “plain” Numpy does accept it.

But the exception shows that you’re trying to modify the uint8 array, in-place, using an int64 scalar.

I’ve had similar cases where in-place modification works best when you ensure you cast the value explicitly to the same datatype.

In this case you can make your mask value also a uint8 in order to make it work.

f(a, 3, 2, numba.uint8(8))

I’m not sure if that’s an unambiguous solution that Numba also could do itself in the background, or that making such an assumption has some side effects, and therefore it needs to be up to the user.

1 Like

It does cast mask to uint8 in non in-place case, so it seems that in-place | operator has unnecessarily strict implementation.