A third-party library (written in C) that I use in my python code is issuing warnings. I want to be able to use the try
except
syntax to properly handle these warnings. Is there a way to do this?

- 143,130
- 81
- 406
- 459

- 29,945
- 39
- 128
- 170
-
2Are those warning just text messages written do stderr? – Fenikso Apr 13 '11 at 05:40
-
1Fenikso: I don't know for sure, seems like real warnings – Boris Gorelik Apr 13 '11 at 05:52
-
1How do you recognize "real warning"? I thought that in C you get real warning during compile. – Fenikso Apr 13 '11 at 06:06
-
`warnings.filterwarnings` does exactly what you want, I don't understand what your issue with it is? – Rosh Oxymoron Apr 13 '11 at 06:19
-
4@Fenikso, @Rosh Oxymoron you were right. My mistake. `warnings.filterwarnigns('error')` does the job. I can't find the original answer that proposed this solution – Boris Gorelik Apr 13 '11 at 06:37
8 Answers
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
.

- 8,187
- 7
- 40
- 58
-
9And if you just want to see a stack trace, the first two lines are all you need. – z0r Feb 23 '17 at 00:59
-
7This is perfect. I just wanted my script to stop execution as soon as the warning was issued, so that I could print relevant debug information and fix the issue. – Praveen Apr 26 '17 at 15:53
-
2You don't need the `filterwarnings` call in order to catch `Warnings`, at least in python 3. it just works. – naught101 Apr 03 '19 at 06:37
-
1The accepted answer does not answer the OP's question. This answer does. This is the answer I was looking for when my search found this question. – Biggsy Jan 24 '20 at 10:39
-
1Converting all warnings to errors can easily become problematic if you're using this within a larger script or software package. Can make things very hard to debug as well – Ben Jeffrey Nov 02 '20 at 14:35
-
2
-
I am still seeing warnings after `warnings.resetwarnings()` in Jupyter notebook. It does not interrupt the program but they were not showing up earlier. It's all `DeprecationWarning`. Any clue? – close2zero Feb 02 '23 at 15:17
To quote from the python handbook (27.6.4. Testing Warnings):
import warnings
def fxn():
warnings.warn("deprecated", DeprecationWarning)
with warnings.catch_warnings(record=True) as w:
# Cause all warnings to always be triggered.
warnings.simplefilter("always")
# Trigger a warning.
fxn()
# Verify some things
assert len(w) == 1
assert issubclass(w[-1].category, DeprecationWarning)
assert "deprecated" in str(w[-1].message)

- 57,944
- 17
- 167
- 143

- 2,863
- 23
- 15
-
11[Here](http://stackoverflow.com/a/15934081/461597) is an answer, that tells you how to use the `try` `except` syntax. – Unapiedra Oct 10 '14 at 13:12
-
2This has the advantage, over niekas's answer, that if ``fnx`` returns something, you keep that result (and still can manage the warning). – Pietro Battiston Mar 22 '19 at 18:22
-
This does not answer the OP's question, which was about handling wanrings, not testing them. However, the answer by niekas below does show how to handle warnings. – Biggsy Jan 24 '20 at 10:42
-
Just a note that the above function will not work if your function only intermittently returns a warning because in the event that `fxn()` does not return a warning, then `w` will be an empty list. If `w` is an empty list (i.e. `[]`), then running the code will give you the following error: `IndexError: list index out of range`. If you're just looking to format or check properties of the captured warnings, then it's better to use a for-loop: `for x in w: print(f'{x.category.__name__}: {str(x.message)}')` – Steven M. Mortimer Jun 14 '20 at 21:29
-
1This approach is useful if one wants to handle warnings without interrupting program execution. – normanius Mar 23 '21 at 12:01
If you just want your script to fail on warnings you can invoke python
with the -W
argument:
python -W error foobar.py

- 4,026
- 3
- 37
- 64
-
9To catch a specific warning type, e.g.: `python -W error::RuntimeWarning foobar.py` – Paul Price Dec 06 '21 at 20:50
Here's a variation that makes it clearer how to work with only your custom warnings.
import warnings
with warnings.catch_warnings(record=True) as w:
# Cause all warnings to always be triggered.
warnings.simplefilter("always")
# Call some code that triggers a custom warning.
functionThatRaisesWarning()
# ignore any non-custom warnings that may be in the list
w = filter(lambda i: issubclass(i.category, UserWarning), w)
if len(w):
# do something with the first warning
email_admins(w[0].message)

- 3,386
- 2
- 25
- 24
Expanding on niekas answer, but using the catch_warnings
context manager that resets the warnings behavior to default after context exit:
import warnings
with warnings.catch_warnings():
warnings.simplefilter("error")
# Code in this block will raise exception for a warning
# Code in this block will have default warning behaviour

- 86,532
- 28
- 194
- 218
Catching all warnings can be problematic. You can catch specific warnings. For example, I needed to catch a Pillow warning:
import warnings
warnings.filterwarnings("error", category=Image.DecompressionBombWarning)
def process_images():
try:
some_process()
except Image.DecompressionBombWarning as e:
print(e)

- 413
- 3
- 6
In some cases, you need use ctypes to turn warnings into errors. For example:
str(b'test') # no error
import warnings
warnings.simplefilter('error', BytesWarning)
str(b'test') # still no error
import ctypes
ctypes.c_int.in_dll(ctypes.pythonapi, 'Py_BytesWarningFlag').value = 2
str(b'test') # this raises an error

- 14,787
- 6
- 68
- 57
-
This answer is constructive simply for showing how to error only in certain warning types. For almost any large software project, if you do `warnings.simplefilter('error')` you won't get the traceback for the warning you saw in the logs, but instead get tracebacks from previously-filtered warnings. Using `simplefilter` is also the quickest way to arrive at your answer if you have some CLI invocation. – AlanSE Apr 12 '19 at 14:08
Just for completeness, you can also export an env variable:
PYTHONWARNINGS=error /usr/bin/run_my_python_utility

- 1,909
- 2
- 20
- 27