Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/numpy/_core/_ufunc_config.py: 37%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

73 statements  

1""" 

2Functions for changing global ufunc configuration 

3 

4This provides helpers which wrap `_get_extobj_dict` and `_make_extobj`, and 

5`_extobj_contextvar` from umath. 

6""" 

7import functools 

8 

9from numpy._utils import set_module 

10 

11from .umath import _extobj_contextvar, _get_extobj_dict, _make_extobj 

12 

13__all__ = [ 

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

15 "errstate" 

16] 

17 

18 

19@set_module('numpy') 

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

21 """ 

22 Set how floating-point errors are handled. 

23 

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

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

26 

27 Parameters 

28 ---------- 

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

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

31 

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

33 - warn: Print a :exc:`RuntimeWarning` (via the Python `warnings` 

34 module). 

35 - raise: Raise a :exc:`FloatingPointError`. 

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

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

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

39 

40 The default is not to change the current behavior. 

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

42 Treatment for division by zero. 

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

44 Treatment for floating-point overflow. 

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

46 Treatment for floating-point underflow. 

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

48 Treatment for invalid floating-point operation. 

49 

50 Returns 

51 ------- 

52 old_settings : dict 

53 Dictionary containing the old settings. 

54 

55 See also 

56 -------- 

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

58 geterr, geterrcall, errstate 

59 

60 

61 Notes 

62 ----- 

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

64 

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

66 - Overflow: result too large to be expressed. 

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

68 was lost. 

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

70 indicates that a NaN was produced. 

71 

72 **Concurrency note:** see :ref:`fp_error_handling` 

73 

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

75 

76 Examples 

77 -------- 

78 >>> import numpy as np 

79 >>> orig_settings = np.seterr(all='ignore') # seterr to known value 

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

81 np.int16(30464) 

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

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

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

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

86 Traceback (most recent call last): 

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

88 FloatingPointError: overflow encountered in scalar multiply 

89 

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

91 >>> np.geterr() 

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

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

94 np.int16(30464) 

95 >>> np.seterr(**orig_settings) # restore original 

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

97 

98 """ 

99 

100 old = _get_extobj_dict() 

101 # The errstate doesn't include call and bufsize, so pop them: 

102 old.pop("call", None) 

103 old.pop("bufsize", None) 

104 

105 extobj = _make_extobj( 

106 all=all, divide=divide, over=over, under=under, invalid=invalid) 

107 _extobj_contextvar.set(extobj) 

108 return old 

109 

110 

111@set_module('numpy') 

112def geterr(): 

113 """ 

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

115 

116 Returns 

117 ------- 

118 res : dict 

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

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

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

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

123 

124 See Also 

125 -------- 

126 geterrcall, seterr, seterrcall 

127 

128 Notes 

129 ----- 

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

131 treatment options, see `seterr`. 

132 

133 **Concurrency note:** see :doc:`/reference/routines.err` 

134 

135 Examples 

136 -------- 

137 >>> import numpy as np 

138 >>> np.geterr() 

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

140 >>> np.arange(3.) / np.arange(3.) # doctest: +SKIP 

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

142 RuntimeWarning: invalid value encountered in divide 

143 

144 >>> oldsettings = np.seterr(all='warn', invalid='raise') 

145 >>> np.geterr() 

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

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

148 Traceback (most recent call last): 

149 ... 

150 FloatingPointError: invalid value encountered in divide 

151 >>> oldsettings = np.seterr(**oldsettings) # restore original 

152 

153 """ 

154 res = _get_extobj_dict() 

155 # The "geterr" doesn't include call and bufsize,: 

156 res.pop("call", None) 

157 res.pop("bufsize", None) 

158 return res 

159 

160 

161@set_module('numpy') 

162def setbufsize(size): 

163 """ 

164 Set the size of the buffer used in ufuncs. 

165 

166 .. versionchanged:: 2.0 

167 The scope of setting the buffer is tied to the `numpy.errstate` 

168 context. Exiting a ``with errstate():`` will also restore the bufsize. 

169 

170 Parameters 

171 ---------- 

172 size : int 

173 Size of buffer. 

174 

175 Returns 

176 ------- 

177 bufsize : int 

178 Previous size of ufunc buffer in bytes. 

179 

180 Notes 

181 ----- 

182 **Concurrency note:** see :doc:`/reference/routines.err` 

183 

184 Examples 

185 -------- 

186 When exiting a `numpy.errstate` context manager the bufsize is restored: 

187 

188 >>> import numpy as np 

189 >>> with np.errstate(): 

190 ... np.setbufsize(4096) 

191 ... print(np.getbufsize()) 

192 ... 

193 8192 

194 4096 

195 >>> np.getbufsize() 

196 8192 

197 

198 """ 

199 if size < 0: 

200 raise ValueError("buffer size must be non-negative") 

201 old = _get_extobj_dict()["bufsize"] 

202 extobj = _make_extobj(bufsize=size) 

203 _extobj_contextvar.set(extobj) 

204 return old 

205 

206 

207@set_module('numpy') 

208def getbufsize(): 

209 """ 

210 Return the size of the buffer used in ufuncs. 

211 

212 Returns 

213 ------- 

214 getbufsize : int 

215 Size of ufunc buffer in bytes. 

216 

217 Notes 

218 ----- 

219 

220 **Concurrency note:** see :doc:`/reference/routines.err` 

221 

222 

223 Examples 

224 -------- 

225 >>> import numpy as np 

226 >>> np.getbufsize() 

227 8192 

228 

229 """ 

230 return _get_extobj_dict()["bufsize"] 

231 

232 

233@set_module('numpy') 

234def seterrcall(func): 

235 """ 

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

237 

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

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

240 the function to call using this function. 

241 

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

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

244 the provided object. 

245 

246 Parameters 

247 ---------- 

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

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

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

251 

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

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

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

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

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

257 

258 [0 0 0 0 divide over under invalid] 

259 

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

261 

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

263 a string. 

264 

265 Returns 

266 ------- 

267 h : callable, log instance or None 

268 The old error handler. 

269 

270 See Also 

271 -------- 

272 seterr, geterr, geterrcall 

273 

274 Notes 

275 ----- 

276 

277 **Concurrency note:** see :doc:`/reference/routines.err` 

278 

279 Examples 

280 -------- 

281 Callback upon error: 

282 

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

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

285 ... 

286 

287 >>> import numpy as np 

288 

289 >>> orig_handler = np.seterrcall(err_handler) 

290 >>> orig_err = np.seterr(all='call') 

291 

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

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

294 array([inf, inf, inf]) 

295 

296 >>> np.seterrcall(orig_handler) 

297 <function err_handler at 0x...> 

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

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

300 

301 Log error message: 

302 

303 >>> class Log: 

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

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

306 ... 

307 

308 >>> log = Log() 

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

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

311 

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

313 LOG: Warning: divide by zero encountered in divide 

314 array([inf, inf, inf]) 

315 

316 >>> np.seterrcall(orig_handler) 

317 <numpy.Log object at 0x...> 

318 >>> np.seterr(**orig_err) 

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

320 

321 """ 

322 old = _get_extobj_dict()["call"] 

323 extobj = _make_extobj(call=func) 

324 _extobj_contextvar.set(extobj) 

325 return old 

326 

327 

328@set_module('numpy') 

329def geterrcall(): 

330 """ 

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

332 

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

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

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

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

337 `seterrcall`. 

338 

339 Returns 

340 ------- 

341 errobj : callable, log instance or None 

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

343 ``None`` is returned. 

344 

345 See Also 

346 -------- 

347 seterrcall, seterr, geterr 

348 

349 Notes 

350 ----- 

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

352 treatment options, see `seterr`. 

353 

354 **Concurrency note:** see :ref:`fp_error_handling` 

355 

356 Examples 

357 -------- 

358 >>> import numpy as np 

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

360 

361 >>> orig_settings = np.seterr(all='call') 

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

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

364 >>> old_handler = np.seterrcall(err_handler) 

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

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

367 array([inf, inf, inf]) 

368 

369 >>> cur_handler = np.geterrcall() 

370 >>> cur_handler is err_handler 

371 True 

372 >>> old_settings = np.seterr(**orig_settings) # restore original 

373 >>> old_handler = np.seterrcall(None) # restore original 

374 

375 """ 

376 return _get_extobj_dict()["call"] 

377 

378 

379class _unspecified: 

380 pass 

381 

382 

383_Unspecified = _unspecified() 

384 

385 

386@set_module('numpy') 

387class errstate: 

388 """ 

389 errstate(**kwargs) 

390 

391 Context manager for floating-point error handling. 

392 

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

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

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

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

397 

398 .. versionchanged:: 1.17.0 

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

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

401 

402 .. versionchanged:: 2.0 

403 `errstate` is now fully thread and asyncio safe, but may not be 

404 entered more than once. 

405 It is not safe to decorate async functions using ``errstate``. 

406 

407 Parameters 

408 ---------- 

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

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

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

412 treatment for the particular error. Possible values are 

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

414 

415 See Also 

416 -------- 

417 seterr, geterr, seterrcall, geterrcall 

418 

419 Notes 

420 ----- 

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

422 treatment options, see `seterr`. 

423 

424 **Concurrency note:** see :ref:`fp_error_handling` 

425 

426 Examples 

427 -------- 

428 >>> import numpy as np 

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

430 

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

432 array([nan, inf, inf]) 

433 >>> with np.errstate(divide='ignore'): 

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

435 array([nan, inf, inf]) 

436 

437 >>> np.sqrt(-1) 

438 np.float64(nan) 

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

440 ... np.sqrt(-1) 

441 Traceback (most recent call last): 

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

443 FloatingPointError: invalid value encountered in sqrt 

444 

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

446 

447 >>> np.geterr() 

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

449 >>> olderr = np.seterr(**olderr) # restore original state 

450 

451 """ 

452 __slots__ = ( 

453 "_all", 

454 "_call", 

455 "_divide", 

456 "_invalid", 

457 "_over", 

458 "_token", 

459 "_under", 

460 ) 

461 

462 def __init__(self, *, call=_Unspecified, 

463 all=None, divide=None, over=None, under=None, invalid=None): 

464 self._token = None 

465 self._call = call 

466 self._all = all 

467 self._divide = divide 

468 self._over = over 

469 self._under = under 

470 self._invalid = invalid 

471 

472 def __enter__(self): 

473 # Note that __call__ duplicates much of this logic 

474 if self._token is not None: 

475 raise TypeError("Cannot enter `np.errstate` twice.") 

476 if self._call is _Unspecified: 

477 extobj = _make_extobj( 

478 all=self._all, divide=self._divide, over=self._over, 

479 under=self._under, invalid=self._invalid) 

480 else: 

481 extobj = _make_extobj( 

482 call=self._call, 

483 all=self._all, divide=self._divide, over=self._over, 

484 under=self._under, invalid=self._invalid) 

485 

486 self._token = _extobj_contextvar.set(extobj) 

487 

488 def __exit__(self, *exc_info): 

489 _extobj_contextvar.reset(self._token) 

490 

491 def __call__(self, func): 

492 # We need to customize `__call__` compared to `ContextDecorator` 

493 # because we must store the token per-thread so cannot store it on 

494 # the instance (we could create a new instance for this). 

495 # This duplicates the code from `__enter__`. 

496 @functools.wraps(func) 

497 def inner(*args, **kwargs): 

498 if self._call is _Unspecified: 

499 extobj = _make_extobj( 

500 all=self._all, divide=self._divide, over=self._over, 

501 under=self._under, invalid=self._invalid) 

502 else: 

503 extobj = _make_extobj( 

504 call=self._call, 

505 all=self._all, divide=self._divide, over=self._over, 

506 under=self._under, invalid=self._invalid) 

507 

508 _token = _extobj_contextvar.set(extobj) 

509 try: 

510 # Call the original, decorated, function: 

511 return func(*args, **kwargs) 

512 finally: 

513 _extobj_contextvar.reset(_token) 

514 

515 return inner