|
10 | 10 | from __future__ import division, print_function |
11 | 11 |
|
12 | 12 | import sys |
13 | | -import re |
14 | 13 | import warnings |
15 | 14 | import gzip |
16 | 15 | from collections import OrderedDict |
|
42 | 41 | #: file-like classes known to hold compressed data |
43 | 42 | COMPRESSED_FILE_LIKES = (gzip.GzipFile, BZ2File) |
44 | 43 |
|
45 | | -_OVERFLOW_FILTER = ( |
46 | | - 'ignore', |
47 | | - re.compile(r'.*overflow.*', re.IGNORECASE | re.UNICODE), |
48 | | - RuntimeWarning, |
49 | | - re.compile(r'', re.UNICODE), |
50 | | - 0) |
51 | | - |
52 | 44 |
|
53 | 45 | class Recoder(object): |
54 | 46 | ''' class to return canonical code(s) from code or aliases |
@@ -1342,32 +1334,36 @@ def _ftype4scaled_finite(tst_arr, slope, inter, direction='read', |
1342 | 1334 | tst_arr = np.atleast_1d(tst_arr) |
1343 | 1335 | slope = np.atleast_1d(slope) |
1344 | 1336 | inter = np.atleast_1d(inter) |
1345 | | - warnings.filters.insert(0, _OVERFLOW_FILTER) |
1346 | | - getattr(warnings, '_filters_mutated', lambda: None)() # PY2 |
1347 | | - # warnings._filters_mutated() # PY3 |
1348 | | - try: |
1349 | | - for ftype in OK_FLOATS[def_ind:]: |
1350 | | - tst_trans = tst_arr.copy() |
1351 | | - slope = slope.astype(ftype) |
1352 | | - inter = inter.astype(ftype) |
| 1337 | + overflow_filter = ('error', '.*overflow.*', RuntimeWarning) |
| 1338 | + for ftype in OK_FLOATS[def_ind:]: |
| 1339 | + tst_trans = tst_arr.copy() |
| 1340 | + slope = slope.astype(ftype) |
| 1341 | + inter = inter.astype(ftype) |
| 1342 | + try: |
1353 | 1343 | if direction == 'read': # as in reading of image from disk |
1354 | 1344 | if slope != 1.0: |
1355 | | - tst_trans = tst_trans * slope |
| 1345 | + # Keep warning contexts small to reduce the odds of a race |
| 1346 | + with warnings.catch_warnings(): |
| 1347 | + # Error on overflows to short circuit the logic |
| 1348 | + warnings.filterwarnings(*overflow_filter) |
| 1349 | + tst_trans = tst_trans * slope |
1356 | 1350 | if inter != 0.0: |
1357 | | - tst_trans = tst_trans + inter |
| 1351 | + with warnings.catch_warnings(): |
| 1352 | + warnings.filterwarnings(*overflow_filter) |
| 1353 | + tst_trans = tst_trans + inter |
1358 | 1354 | elif direction == 'write': |
1359 | 1355 | if inter != 0.0: |
1360 | | - tst_trans = tst_trans - inter |
| 1356 | + with warnings.catch_warnings(): |
| 1357 | + warnings.filterwarnings(*overflow_filter) |
| 1358 | + tst_trans = tst_trans - inter |
1361 | 1359 | if slope != 1.0: |
1362 | | - tst_trans = tst_trans / slope |
| 1360 | + with warnings.catch_warnings(): |
| 1361 | + warnings.filterwarnings(*overflow_filter) |
| 1362 | + tst_trans = tst_trans / slope |
| 1363 | + # Double-check that result is finite |
1363 | 1364 | if np.all(np.isfinite(tst_trans)): |
1364 | 1365 | return ftype |
1365 | | - finally: |
1366 | | - try: |
1367 | | - warnings.filters.remove(_OVERFLOW_FILTER) |
1368 | | - getattr(warnings, '_filters_mutated', lambda: None)() # PY2 |
1369 | | - # warnings._filters_mutated() # PY3 |
1370 | | - except ValueError: |
| 1366 | + except RuntimeWarning: |
1371 | 1367 | pass |
1372 | 1368 | raise ValueError('Overflow using highest floating point type') |
1373 | 1369 |
|
|
0 commit comments