Coverage for src/bioimageio/core/_magic_tensor_ops.py: 73%

158 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-10-14 08:35 +0000

1# this file was modified from the generated 

2# https://github.com/pydata/xarray/blob/cf3655968b8b12cc0ecd28fb324e63fb94d5e7e2/xarray/core/_typed_ops.py 

3# TODO: should we generate this ourselves? 

4# TODO: test these magic methods 

5import operator 

6from typing import Any, Callable 

7 

8from typing_extensions import Self 

9from xarray.core import nputils 

10 

11try: 

12 # xarray >= 2025.03 

13 from xarray.computation import ops 

14except ImportError: 

15 # xarray < 2025.03 

16 from xarray.core import ops # type: ignore 

17 

18 

19class MagicTensorOpsMixin: 

20 __slots__ = () 

21 _Compatible = Any 

22 

23 def _binary_op( 

24 self, 

25 other: _Compatible, 

26 f: Callable[[Any, Any], Any], 

27 reflexive: bool = False, 

28 ) -> Self: 

29 raise NotImplementedError 

30 

31 def __add__(self, other: _Compatible) -> Self: 

32 return self._binary_op(other, operator.add) 

33 

34 def __sub__(self, other: _Compatible) -> Self: 

35 return self._binary_op(other, operator.sub) 

36 

37 def __mul__(self, other: _Compatible) -> Self: 

38 return self._binary_op(other, operator.mul) 

39 

40 def __pow__(self, other: _Compatible) -> Self: 

41 return self._binary_op(other, operator.pow) 

42 

43 def __truediv__(self, other: _Compatible) -> Self: 

44 return self._binary_op(other, operator.truediv) 

45 

46 def __floordiv__(self, other: _Compatible) -> Self: 

47 return self._binary_op(other, operator.floordiv) 

48 

49 def __mod__(self, other: _Compatible) -> Self: 

50 return self._binary_op(other, operator.mod) 

51 

52 def __and__(self, other: _Compatible) -> Self: 

53 return self._binary_op(other, operator.and_) 

54 

55 def __xor__(self, other: _Compatible) -> Self: 

56 return self._binary_op(other, operator.xor) 

57 

58 def __or__(self, other: _Compatible) -> Self: 

59 return self._binary_op(other, operator.or_) 

60 

61 def __lshift__(self, other: _Compatible) -> Self: 

62 return self._binary_op(other, operator.lshift) 

63 

64 def __rshift__(self, other: _Compatible) -> Self: 

65 return self._binary_op(other, operator.rshift) 

66 

67 def __lt__(self, other: _Compatible) -> Self: 

68 return self._binary_op(other, operator.lt) 

69 

70 def __le__(self, other: _Compatible) -> Self: 

71 return self._binary_op(other, operator.le) 

72 

73 def __gt__(self, other: _Compatible) -> Self: 

74 return self._binary_op(other, operator.gt) 

75 

76 def __ge__(self, other: _Compatible) -> Self: 

77 return self._binary_op(other, operator.ge) 

78 

79 def __eq__(self, other: _Compatible) -> Self: # type: ignore[override] 

80 return self._binary_op( 

81 other, 

82 nputils.array_eq, # pyright: ignore[reportUnknownArgumentType] 

83 ) 

84 

85 def __ne__(self, other: _Compatible) -> Self: # type: ignore[override] 

86 return self._binary_op( 

87 other, 

88 nputils.array_ne, # pyright: ignore[reportUnknownArgumentType] 

89 ) 

90 

91 # When __eq__ is defined but __hash__ is not, then an object is unhashable, 

92 # and it should be declared as follows: 

93 __hash__: None # type:ignore[assignment] 

94 

95 def __radd__(self, other: _Compatible) -> Self: 

96 return self._binary_op(other, operator.add, reflexive=True) 

97 

98 def __rsub__(self, other: _Compatible) -> Self: 

99 return self._binary_op(other, operator.sub, reflexive=True) 

100 

101 def __rmul__(self, other: _Compatible) -> Self: 

102 return self._binary_op(other, operator.mul, reflexive=True) 

103 

104 def __rpow__(self, other: _Compatible) -> Self: 

105 return self._binary_op(other, operator.pow, reflexive=True) 

106 

107 def __rtruediv__(self, other: _Compatible) -> Self: 

108 return self._binary_op(other, operator.truediv, reflexive=True) 

109 

110 def __rfloordiv__(self, other: _Compatible) -> Self: 

111 return self._binary_op(other, operator.floordiv, reflexive=True) 

112 

113 def __rmod__(self, other: _Compatible) -> Self: 

114 return self._binary_op(other, operator.mod, reflexive=True) 

115 

116 def __rand__(self, other: _Compatible) -> Self: 

117 return self._binary_op(other, operator.and_, reflexive=True) 

118 

119 def __rxor__(self, other: _Compatible) -> Self: 

120 return self._binary_op(other, operator.xor, reflexive=True) 

121 

122 def __ror__(self, other: _Compatible) -> Self: 

123 return self._binary_op(other, operator.or_, reflexive=True) 

124 

125 def _inplace_binary_op( 

126 self, other: _Compatible, f: Callable[[Any, Any], Any] 

127 ) -> Self: 

128 raise NotImplementedError 

129 

130 def __iadd__(self, other: _Compatible) -> Self: 

131 return self._inplace_binary_op(other, operator.iadd) 

132 

133 def __isub__(self, other: _Compatible) -> Self: 

134 return self._inplace_binary_op(other, operator.isub) 

135 

136 def __imul__(self, other: _Compatible) -> Self: 

137 return self._inplace_binary_op(other, operator.imul) 

138 

139 def __ipow__(self, other: _Compatible) -> Self: 

140 return self._inplace_binary_op(other, operator.ipow) 

141 

142 def __itruediv__(self, other: _Compatible) -> Self: 

143 return self._inplace_binary_op(other, operator.itruediv) 

144 

145 def __ifloordiv__(self, other: _Compatible) -> Self: 

146 return self._inplace_binary_op(other, operator.ifloordiv) 

147 

148 def __imod__(self, other: _Compatible) -> Self: 

149 return self._inplace_binary_op(other, operator.imod) 

150 

151 def __iand__(self, other: _Compatible) -> Self: 

152 return self._inplace_binary_op(other, operator.iand) 

153 

154 def __ixor__(self, other: _Compatible) -> Self: 

155 return self._inplace_binary_op(other, operator.ixor) 

156 

157 def __ior__(self, other: _Compatible) -> Self: 

158 return self._inplace_binary_op(other, operator.ior) 

159 

160 def __ilshift__(self, other: _Compatible) -> Self: 

161 return self._inplace_binary_op(other, operator.ilshift) 

162 

163 def __irshift__(self, other: _Compatible) -> Self: 

164 return self._inplace_binary_op(other, operator.irshift) 

165 

166 def _unary_op(self, f: Callable[[Any], Any], *args: Any, **kwargs: Any) -> Self: 

167 raise NotImplementedError 

168 

169 def __neg__(self) -> Self: 

170 return self._unary_op(operator.neg) 

171 

172 def __pos__(self) -> Self: 

173 return self._unary_op(operator.pos) 

174 

175 def __abs__(self) -> Self: 

176 return self._unary_op(operator.abs) 

177 

178 def __invert__(self) -> Self: 

179 return self._unary_op(operator.invert) 

180 

181 def round(self, *args: Any, **kwargs: Any) -> Self: 

182 return self._unary_op( 

183 ops.round_, # pyright: ignore[reportUnknownArgumentType] 

184 *args, 

185 **kwargs, 

186 ) 

187 

188 def argsort(self, *args: Any, **kwargs: Any) -> Self: 

189 return self._unary_op( 

190 ops.argsort, # pyright: ignore[reportUnknownArgumentType] 

191 *args, 

192 **kwargs, 

193 ) 

194 

195 def conj(self, *args: Any, **kwargs: Any) -> Self: 

196 return self._unary_op( 

197 ops.conj, # pyright: ignore[reportUnknownArgumentType] 

198 *args, 

199 **kwargs, 

200 ) 

201 

202 def conjugate(self, *args: Any, **kwargs: Any) -> Self: 

203 return self._unary_op( 

204 ops.conjugate, # pyright: ignore[reportUnknownArgumentType] 

205 *args, 

206 **kwargs, 

207 ) 

208 

209 __add__.__doc__ = operator.add.__doc__ 

210 __sub__.__doc__ = operator.sub.__doc__ 

211 __mul__.__doc__ = operator.mul.__doc__ 

212 __pow__.__doc__ = operator.pow.__doc__ 

213 __truediv__.__doc__ = operator.truediv.__doc__ 

214 __floordiv__.__doc__ = operator.floordiv.__doc__ 

215 __mod__.__doc__ = operator.mod.__doc__ 

216 __and__.__doc__ = operator.and_.__doc__ 

217 __xor__.__doc__ = operator.xor.__doc__ 

218 __or__.__doc__ = operator.or_.__doc__ 

219 __lshift__.__doc__ = operator.lshift.__doc__ 

220 __rshift__.__doc__ = operator.rshift.__doc__ 

221 __lt__.__doc__ = operator.lt.__doc__ 

222 __le__.__doc__ = operator.le.__doc__ 

223 __gt__.__doc__ = operator.gt.__doc__ 

224 __ge__.__doc__ = operator.ge.__doc__ 

225 __eq__.__doc__ = nputils.array_eq.__doc__ 

226 __ne__.__doc__ = nputils.array_ne.__doc__ 

227 __radd__.__doc__ = operator.add.__doc__ 

228 __rsub__.__doc__ = operator.sub.__doc__ 

229 __rmul__.__doc__ = operator.mul.__doc__ 

230 __rpow__.__doc__ = operator.pow.__doc__ 

231 __rtruediv__.__doc__ = operator.truediv.__doc__ 

232 __rfloordiv__.__doc__ = operator.floordiv.__doc__ 

233 __rmod__.__doc__ = operator.mod.__doc__ 

234 __rand__.__doc__ = operator.and_.__doc__ 

235 __rxor__.__doc__ = operator.xor.__doc__ 

236 __ror__.__doc__ = operator.or_.__doc__ 

237 __iadd__.__doc__ = operator.iadd.__doc__ 

238 __isub__.__doc__ = operator.isub.__doc__ 

239 __imul__.__doc__ = operator.imul.__doc__ 

240 __ipow__.__doc__ = operator.ipow.__doc__ 

241 __itruediv__.__doc__ = operator.itruediv.__doc__ 

242 __ifloordiv__.__doc__ = operator.ifloordiv.__doc__ 

243 __imod__.__doc__ = operator.imod.__doc__ 

244 __iand__.__doc__ = operator.iand.__doc__ 

245 __ixor__.__doc__ = operator.ixor.__doc__ 

246 __ior__.__doc__ = operator.ior.__doc__ 

247 __ilshift__.__doc__ = operator.ilshift.__doc__ 

248 __irshift__.__doc__ = operator.irshift.__doc__ 

249 __neg__.__doc__ = operator.neg.__doc__ 

250 __pos__.__doc__ = operator.pos.__doc__ 

251 __abs__.__doc__ = operator.abs.__doc__ 

252 __invert__.__doc__ = operator.invert.__doc__