Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/numpy/core/_ufunc_config.py: 70%

87 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1""" 

2Functions for changing global ufunc configuration 

3 

4This provides helpers which wrap `umath.geterrobj` and `umath.seterrobj` 

5""" 

6import collections.abc 

7import contextlib 

8 

9from .overrides import set_module 

10from .umath import ( 

11 UFUNC_BUFSIZE_DEFAULT, 

12 ERR_IGNORE, ERR_WARN, ERR_RAISE, ERR_CALL, ERR_PRINT, ERR_LOG, ERR_DEFAULT, 

13 SHIFT_DIVIDEBYZERO, SHIFT_OVERFLOW, SHIFT_UNDERFLOW, SHIFT_INVALID, 

14) 

15from . import umath 

16 

17__all__ = [ 

18 "seterr", "geterr", "setbufsize", "getbufsize", "seterrcall", "geterrcall", 

19 "errstate", 

20] 

21 

22_errdict = {"ignore": ERR_IGNORE, 

23 "warn": ERR_WARN, 

24 "raise": ERR_RAISE, 

25 "call": ERR_CALL, 

26 "print": ERR_PRINT, 

27 "log": ERR_LOG} 

28 

29_errdict_rev = {value: key for key, value in _errdict.items()} 

30 

31 

32@set_module('numpy') 

33def seterr(all=None, divide=None, over=None, under=None, invalid=None): 

34 """ 

35 Set how floating-point errors are handled. 

36 

37 Note that operations on integer scalar types (such as `int16`) are 

38 handled like floating point, and are affected by these settings. 

39 

40 Parameters 

41 ---------- 

42 all : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional 

43 Set treatment for all types of floating-point errors at once: 

44 

45 - ignore: Take no action when the exception occurs. 

46 - warn: Print a `RuntimeWarning` (via the Python `warnings` module). 

47 - raise: Raise a `FloatingPointError`. 

48 - call: Call a function specified using the `seterrcall` function. 

49 - print: Print a warning directly to ``stdout``. 

50 - log: Record error in a Log object specified by `seterrcall`. 

51 

52 The default is not to change the current behavior. 

53 divide : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional 

54 Treatment for division by zero. 

55 over : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional 

56 Treatment for floating-point overflow. 

57 under : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional 

58 Treatment for floating-point underflow. 

59 invalid : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional 

60 Treatment for invalid floating-point operation. 

61 

62 Returns 

63 ------- 

64 old_settings : dict 

65 Dictionary containing the old settings. 

66 

67 See also 

68 -------- 

69 seterrcall : Set a callback function for the 'call' mode. 

70 geterr, geterrcall, errstate 

71 

72 Notes 

73 ----- 

74 The floating-point exceptions are defined in the IEEE 754 standard [1]_: 

75 

76 - Division by zero: infinite result obtained from finite numbers. 

77 - Overflow: result too large to be expressed. 

78 - Underflow: result so close to zero that some precision 

79 was lost. 

80 - Invalid operation: result is not an expressible number, typically 

81 indicates that a NaN was produced. 

82 

83 .. [1] https://en.wikipedia.org/wiki/IEEE_754 

84 

85 Examples 

86 -------- 

87 >>> old_settings = np.seterr(all='ignore') #seterr to known value 

88 >>> np.seterr(over='raise') 

89 {'divide': 'ignore', 'over': 'ignore', 'under': 'ignore', 'invalid': 'ignore'} 

90 >>> np.seterr(**old_settings) # reset to default 

91 {'divide': 'ignore', 'over': 'raise', 'under': 'ignore', 'invalid': 'ignore'} 

92 

93 >>> np.int16(32000) * np.int16(3) 

94 30464 

95 >>> old_settings = np.seterr(all='warn', over='raise') 

96 >>> np.int16(32000) * np.int16(3) 

97 Traceback (most recent call last): 

98 File "<stdin>", line 1, in <module> 

99 FloatingPointError: overflow encountered in short_scalars 

100 

101 >>> old_settings = np.seterr(all='print') 

102 >>> np.geterr() 

103 {'divide': 'print', 'over': 'print', 'under': 'print', 'invalid': 'print'} 

104 >>> np.int16(32000) * np.int16(3) 

105 30464 

106 

107 """ 

108 

109 pyvals = umath.geterrobj() 

110 old = geterr() 

111 

112 if divide is None: 

113 divide = all or old['divide'] 

114 if over is None: 

115 over = all or old['over'] 

116 if under is None: 

117 under = all or old['under'] 

118 if invalid is None: 

119 invalid = all or old['invalid'] 

120 

121 maskvalue = ((_errdict[divide] << SHIFT_DIVIDEBYZERO) + 

122 (_errdict[over] << SHIFT_OVERFLOW) + 

123 (_errdict[under] << SHIFT_UNDERFLOW) + 

124 (_errdict[invalid] << SHIFT_INVALID)) 

125 

126 pyvals[1] = maskvalue 

127 umath.seterrobj(pyvals) 

128 return old 

129 

130 

131@set_module('numpy') 

132def geterr(): 

133 """ 

134 Get the current way of handling floating-point errors. 

135 

136 Returns 

137 ------- 

138 res : dict 

139 A dictionary with keys "divide", "over", "under", and "invalid", 

140 whose values are from the strings "ignore", "print", "log", "warn", 

141 "raise", and "call". The keys represent possible floating-point 

142 exceptions, and the values define how these exceptions are handled. 

143 

144 See Also 

145 -------- 

146 geterrcall, seterr, seterrcall 

147 

148 Notes 

149 ----- 

150 For complete documentation of the types of floating-point exceptions and 

151 treatment options, see `seterr`. 

152 

153 Examples 

154 -------- 

155 >>> np.geterr() 

156 {'divide': 'warn', 'over': 'warn', 'under': 'ignore', 'invalid': 'warn'} 

157 >>> np.arange(3.) / np.arange(3.) 

158 array([nan, 1., 1.]) 

159 

160 >>> oldsettings = np.seterr(all='warn', over='raise') 

161 >>> np.geterr() 

162 {'divide': 'warn', 'over': 'raise', 'under': 'warn', 'invalid': 'warn'} 

163 >>> np.arange(3.) / np.arange(3.) 

164 array([nan, 1., 1.]) 

165 

166 """ 

167 maskvalue = umath.geterrobj()[1] 

168 mask = 7 

169 res = {} 

170 val = (maskvalue >> SHIFT_DIVIDEBYZERO) & mask 

171 res['divide'] = _errdict_rev[val] 

172 val = (maskvalue >> SHIFT_OVERFLOW) & mask 

173 res['over'] = _errdict_rev[val] 

174 val = (maskvalue >> SHIFT_UNDERFLOW) & mask 

175 res['under'] = _errdict_rev[val] 

176 val = (maskvalue >> SHIFT_INVALID) & mask 

177 res['invalid'] = _errdict_rev[val] 

178 return res 

179 

180 

181@set_module('numpy') 

182def setbufsize(size): 

183 """ 

184 Set the size of the buffer used in ufuncs. 

185 

186 Parameters 

187 ---------- 

188 size : int 

189 Size of buffer. 

190 

191 """ 

192 if size > 10e6: 

193 raise ValueError("Buffer size, %s, is too big." % size) 

194 if size < 5: 

195 raise ValueError("Buffer size, %s, is too small." % size) 

196 if size % 16 != 0: 

197 raise ValueError("Buffer size, %s, is not a multiple of 16." % size) 

198 

199 pyvals = umath.geterrobj() 

200 old = getbufsize() 

201 pyvals[0] = size 

202 umath.seterrobj(pyvals) 

203 return old 

204 

205 

206@set_module('numpy') 

207def getbufsize(): 

208 """ 

209 Return the size of the buffer used in ufuncs. 

210 

211 Returns 

212 ------- 

213 getbufsize : int 

214 Size of ufunc buffer in bytes. 

215 

216 """ 

217 return umath.geterrobj()[0] 

218 

219 

220@set_module('numpy') 

221def seterrcall(func): 

222 """ 

223 Set the floating-point error callback function or log object. 

224 

225 There are two ways to capture floating-point error messages. The first 

226 is to set the error-handler to 'call', using `seterr`. Then, set 

227 the function to call using this function. 

228 

229 The second is to set the error-handler to 'log', using `seterr`. 

230 Floating-point errors then trigger a call to the 'write' method of 

231 the provided object. 

232 

233 Parameters 

234 ---------- 

235 func : callable f(err, flag) or object with write method 

236 Function to call upon floating-point errors ('call'-mode) or 

237 object whose 'write' method is used to log such message ('log'-mode). 

238 

239 The call function takes two arguments. The first is a string describing 

240 the type of error (such as "divide by zero", "overflow", "underflow", 

241 or "invalid value"), and the second is the status flag. The flag is a 

242 byte, whose four least-significant bits indicate the type of error, one 

243 of "divide", "over", "under", "invalid":: 

244 

245 [0 0 0 0 divide over under invalid] 

246 

247 In other words, ``flags = divide + 2*over + 4*under + 8*invalid``. 

248 

249 If an object is provided, its write method should take one argument, 

250 a string. 

251 

252 Returns 

253 ------- 

254 h : callable, log instance or None 

255 The old error handler. 

256 

257 See Also 

258 -------- 

259 seterr, geterr, geterrcall 

260 

261 Examples 

262 -------- 

263 Callback upon error: 

264 

265 >>> def err_handler(type, flag): 

266 ... print("Floating point error (%s), with flag %s" % (type, flag)) 

267 ... 

268 

269 >>> saved_handler = np.seterrcall(err_handler) 

270 >>> save_err = np.seterr(all='call') 

271 

272 >>> np.array([1, 2, 3]) / 0.0 

273 Floating point error (divide by zero), with flag 1 

274 array([inf, inf, inf]) 

275 

276 >>> np.seterrcall(saved_handler) 

277 <function err_handler at 0x...> 

278 >>> np.seterr(**save_err) 

279 {'divide': 'call', 'over': 'call', 'under': 'call', 'invalid': 'call'} 

280 

281 Log error message: 

282 

283 >>> class Log: 

284 ... def write(self, msg): 

285 ... print("LOG: %s" % msg) 

286 ... 

287 

288 >>> log = Log() 

289 >>> saved_handler = np.seterrcall(log) 

290 >>> save_err = np.seterr(all='log') 

291 

292 >>> np.array([1, 2, 3]) / 0.0 

293 LOG: Warning: divide by zero encountered in divide 

294 array([inf, inf, inf]) 

295 

296 >>> np.seterrcall(saved_handler) 

297 <numpy.core.numeric.Log object at 0x...> 

298 >>> np.seterr(**save_err) 

299 {'divide': 'log', 'over': 'log', 'under': 'log', 'invalid': 'log'} 

300 

301 """ 

302 if func is not None and not isinstance(func, collections.abc.Callable): 

303 if (not hasattr(func, 'write') or 

304 not isinstance(func.write, collections.abc.Callable)): 

305 raise ValueError("Only callable can be used as callback") 

306 pyvals = umath.geterrobj() 

307 old = geterrcall() 

308 pyvals[2] = func 

309 umath.seterrobj(pyvals) 

310 return old 

311 

312 

313@set_module('numpy') 

314def geterrcall(): 

315 """ 

316 Return the current callback function used on floating-point errors. 

317 

318 When the error handling for a floating-point error (one of "divide", 

319 "over", "under", or "invalid") is set to 'call' or 'log', the function 

320 that is called or the log instance that is written to is returned by 

321 `geterrcall`. This function or log instance has been set with 

322 `seterrcall`. 

323 

324 Returns 

325 ------- 

326 errobj : callable, log instance or None 

327 The current error handler. If no handler was set through `seterrcall`, 

328 ``None`` is returned. 

329 

330 See Also 

331 -------- 

332 seterrcall, seterr, geterr 

333 

334 Notes 

335 ----- 

336 For complete documentation of the types of floating-point exceptions and 

337 treatment options, see `seterr`. 

338 

339 Examples 

340 -------- 

341 >>> np.geterrcall() # we did not yet set a handler, returns None 

342 

343 >>> oldsettings = np.seterr(all='call') 

344 >>> def err_handler(type, flag): 

345 ... print("Floating point error (%s), with flag %s" % (type, flag)) 

346 >>> oldhandler = np.seterrcall(err_handler) 

347 >>> np.array([1, 2, 3]) / 0.0 

348 Floating point error (divide by zero), with flag 1 

349 array([inf, inf, inf]) 

350 

351 >>> cur_handler = np.geterrcall() 

352 >>> cur_handler is err_handler 

353 True 

354 

355 """ 

356 return umath.geterrobj()[2] 

357 

358 

359class _unspecified: 

360 pass 

361 

362 

363_Unspecified = _unspecified() 

364 

365 

366@set_module('numpy') 

367class errstate(contextlib.ContextDecorator): 

368 """ 

369 errstate(**kwargs) 

370 

371 Context manager for floating-point error handling. 

372 

373 Using an instance of `errstate` as a context manager allows statements in 

374 that context to execute with a known error handling behavior. Upon entering 

375 the context the error handling is set with `seterr` and `seterrcall`, and 

376 upon exiting it is reset to what it was before. 

377 

378 .. versionchanged:: 1.17.0 

379 `errstate` is also usable as a function decorator, saving 

380 a level of indentation if an entire function is wrapped. 

381 See :py:class:`contextlib.ContextDecorator` for more information. 

382 

383 Parameters 

384 ---------- 

385 kwargs : {divide, over, under, invalid} 

386 Keyword arguments. The valid keywords are the possible floating-point 

387 exceptions. Each keyword should have a string value that defines the 

388 treatment for the particular error. Possible values are 

389 {'ignore', 'warn', 'raise', 'call', 'print', 'log'}. 

390 

391 See Also 

392 -------- 

393 seterr, geterr, seterrcall, geterrcall 

394 

395 Notes 

396 ----- 

397 For complete documentation of the types of floating-point exceptions and 

398 treatment options, see `seterr`. 

399 

400 Examples 

401 -------- 

402 >>> olderr = np.seterr(all='ignore') # Set error handling to known state. 

403 

404 >>> np.arange(3) / 0. 

405 array([nan, inf, inf]) 

406 >>> with np.errstate(divide='warn'): 

407 ... np.arange(3) / 0. 

408 array([nan, inf, inf]) 

409 

410 >>> np.sqrt(-1) 

411 nan 

412 >>> with np.errstate(invalid='raise'): 

413 ... np.sqrt(-1) 

414 Traceback (most recent call last): 

415 File "<stdin>", line 2, in <module> 

416 FloatingPointError: invalid value encountered in sqrt 

417 

418 Outside the context the error handling behavior has not changed: 

419 

420 >>> np.geterr() 

421 {'divide': 'ignore', 'over': 'ignore', 'under': 'ignore', 'invalid': 'ignore'} 

422 

423 """ 

424 

425 def __init__(self, *, call=_Unspecified, **kwargs): 

426 self.call = call 

427 self.kwargs = kwargs 

428 

429 def __enter__(self): 

430 self.oldstate = seterr(**self.kwargs) 

431 if self.call is not _Unspecified: 431 ↛ 432line 431 didn't jump to line 432, because the condition on line 431 was never true

432 self.oldcall = seterrcall(self.call) 

433 

434 def __exit__(self, *exc_info): 

435 seterr(**self.oldstate) 

436 if self.call is not _Unspecified: 436 ↛ 437line 436 didn't jump to line 437, because the condition on line 436 was never true

437 seterrcall(self.oldcall) 

438 

439 

440def _setdef(): 

441 defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None] 

442 umath.seterrobj(defval) 

443 

444 

445# set the default values 

446_setdef()