(mocker)
| 1232 | |
| 1233 | |
| 1234 | def test_binary_operator_delegation(mocker): |
| 1235 | # Binary operator delegation in Dask should follow Numpy's: |
| 1236 | # https://numpy.org/neps/nep-0013-ufunc-overrides.html#behavior-in-combination-with-python-s-binary-operations |
| 1237 | |
| 1238 | x = from_array([1, 2, 3]) |
| 1239 | |
| 1240 | # Mock various types of `other` objects |
| 1241 | ufunc_none = mocker.Mock() |
| 1242 | ufunc_none.__array_ufunc__ = None |
| 1243 | ufunc_none.__radd__ = mocker.Mock() |
| 1244 | |
| 1245 | ufunc_high_priority = mocker.Mock() |
| 1246 | ufunc_high_priority.__array_priority__ = x.__array_priority__ + 1 |
| 1247 | ufunc_high_priority.__radd__ = mocker.Mock() |
| 1248 | |
| 1249 | ufunc_low_priority = mocker.Mock() |
| 1250 | ufunc_low_priority.__array_priority__ = x.__array_priority__ - 1 |
| 1251 | ufunc_low_priority.__radd__ = mocker.Mock() |
| 1252 | |
| 1253 | ufunc_no_priority = mocker.Mock() |
| 1254 | ufunc_no_priority.__radd__ = mocker.Mock() |
| 1255 | |
| 1256 | # If `other.__array_ufunc__ is None`, delegates back to Python |
| 1257 | # and therefore call reflected operator on `other` |
| 1258 | x + ufunc_none |
| 1259 | ufunc_none.__radd__.assert_called_once() |
| 1260 | |
| 1261 | # If the `__array_ufunc__` attribute is absent on other and |
| 1262 | # `other.__array_priority__ > self.__array_priority__`, also delegates back |
| 1263 | # to Python and therefore call reflected operator on `other` |
| 1264 | x + ufunc_high_priority |
| 1265 | ufunc_high_priority.__radd__.assert_called_once() |
| 1266 | |
| 1267 | # If `other.__array_priority__ <= self.__array_priority__`, does not |
| 1268 | # delegate (here it raises an error) |
| 1269 | with pytest.raises(TypeError): |
| 1270 | x + ufunc_low_priority |
| 1271 | ufunc_low_priority.__radd__.assert_not_called() |
| 1272 | |
| 1273 | # If `other.__array_priority__` is absent, does not delegate (raises) |
| 1274 | with pytest.raises(TypeError): |
| 1275 | x + ufunc_no_priority |
| 1276 | ufunc_no_priority.__radd__.assert_not_called() |
| 1277 | |
| 1278 | |
| 1279 | @pytest.mark.filterwarnings("ignore:overflow encountered in cast") # numpy >=2.0 |
nothing calls this directly
no test coverage detected