In Python, how does one catch warnings as if they were exceptions?
To handle warnings as errors simply use this:
import warnings
warnings.filterwarnings("error")
After this you will be able to catch warnings same as errors, e.g. this will work:
try:
some_heavy_calculations()
except RuntimeWarning:
breakpoint()
You can also reset the behaviour of warnings by running:
warnings.resetwarnings()
P.S. Added this answer because the best answer in comments contains misspelling: filterwarnigns
instead of filterwarnings
.
Is it possible to capture all warnings raised in a try block in python?
Were you expecting something like the following:
import warnings
warnings.filterwarnings('error')
def warning_func():
print('hello')
warnings.warn(Warning('Warn1'))
print('hi')
warnings.warn(Warning('Warn2'))
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
warning_func()
print(w)
How do I catch a numpy warning like it's an exception (not just for testing)?
It seems that your configuration is using the print
option for numpy.seterr
:
>>> import numpy as np
>>> np.array([1])/0 #'warn' mode
__main__:1: RuntimeWarning: divide by zero encountered in divide
array([0])
>>> np.seterr(all='print')
{'over': 'warn', 'divide': 'warn', 'invalid': 'warn', 'under': 'ignore'}
>>> np.array([1])/0 #'print' mode
Warning: divide by zero encountered in divide
array([0])
This means that the warning you see is not a real warning, but it's just some characters printed to stdout
(see the documentation for seterr
). If you want to catch it you can:
- Use
numpy.seterr(all='raise')
which will directly raise the exception. This however changes the behaviour of all the operations, so it's a pretty big change in behaviour. - Use
numpy.seterr(all='warn')
, which will transform the printed warning in a real warning and you'll be able to use the above solution to localize this change in behaviour.
Once you actually have a warning, you can use the warnings
module to control how the warnings should be treated:
>>> import warnings
>>>
>>> warnings.filterwarnings('error')
>>>
>>> try:
... warnings.warn(Warning())
... except Warning:
... print 'Warning was raised as an exception!'
...
Warning was raised as an exception!
Read carefully the documentation for filterwarnings
since it allows you to filter only the warning you want and has other options. I'd also consider looking at catch_warnings
which is a context manager which automatically resets the original filterwarnings
function:
>>> import warnings
>>> with warnings.catch_warnings():
... warnings.filterwarnings('error')
... try:
... warnings.warn(Warning())
... except Warning: print 'Raised!'
...
Raised!
>>> try:
... warnings.warn(Warning())
... except Warning: print 'Not raised!'
...
__main__:2: Warning:
Catching numpy runtimewarning as exception and suppressing them
Thanks to Jürg Merlin Spaak for his comment, I found a better and simpler solution. It's obviously better to catch the exception outside the function which I reverted back to the original version:
def ExtractValues(d):
for v in d.values():
if isinstance(v, dict):
yield from ExtractValues(v)
else:
if isinstance(v,list):
v = np.mean(v)
yield v
I've set everything on warn in the main piece of the of the code:
np.seterr(all='warn')
Then catch them:
with warnings.catch_warnings():
warnings.filterwarnings('error')
try:
raw_features = list(ExtractValues(data))
except Warning as e:
print('Houston, we have a warning:', e)
print('The bad guy is: ' + current_file)
print('This sample will not be considered.')
pass
else:
#Whatever
Worth noting for whoever comes here for the same exception. I succeeded to catch both warnings, but print(e)
will tell you only "mean of empty slice". I can guess why, but I'm too tired to further investigate.
Raise warning in Python without interrupting program
You shouldn't raise
the warning, you should be using warnings
module. By raising it you're generating error, rather than warning.
Related Topics
What's a Good Equivalent to Subprocess.Check_Call That Returns the Contents of Stdout
Python Pack() and Grid() Methods Together
How to Log Server Errors on Django Sites
Redirect While Passing Arguments
Selecting Pandas Column by Location
Python - Pysftp/Paramiko - Verify Host Key Using Its Fingerprint
Flask Importerror: No Module Named Flask
Find the Division Remainder of a Number
Difference Between Pygame.Display.Update and Pygame.Display.Flip
How to Rotate a Matplotlib Plot Through 90 Degrees
Pandas Selecting by Label Sometimes Return Series, Sometimes Returns Dataframe
Reading Two Text Files Line by Line Simultaneously
Determine Complete Django Url Configuration
Pip Connection Failure: Cannot Fetch Index Base Url Http://Pypi.Python.Org/Simple/