Warning
A warning is an exception class that is normally not raised: warnings.warn() hands it to the filters, which print it once, ignore it, or — with "error" — raise it like any other exception.
Demo
import warnings with warnings.catch_warnings(record=True) as caught: warnings.simplefilter('default') for i in range(3): warnings.warn('old API', UserWarning) [str(w.message) for w in caught]
Compare default and always: the default action records the warning once for that line, so a warning inside a loop appears a single time; always records all three. error stops at the first call with an uncaught UserWarning — that is what python -W error does to your whole program. The action must be spelled exactly: 'Error' is a ValueError, not a filter.
Constructor
| Name | Type | Required | Description |
|---|---|---|---|
| *args | object | no | The message. warnings.warn(text, Category) builds Category(text) for you. |
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| args | tuple | The constructor arguments; args[0] is the message text. |
| w.message / w.category / w.filename / w.lineno | record fields | With catch_warnings(record=True) each recorded item carries the Warning instance, its class, and the location it is attributed to (see stacklevel). |
Common patterns
import warnings def connect(host, timeout=None): if timeout is None: warnings.warn('no timeout set; connections may hang', RuntimeWarning, stacklevel=2)
import warnings warnings.filterwarnings('ignore', message='.*unclosed.*', category=ResourceWarning)
import warnings def test_no_warnings(): with warnings.catch_warnings(): warnings.simplefilter('error') run_the_code()
Examples
Pitfalls
import warnings with warnings.catch_warnings(record=True) as caught: warnings.simplefilter('ignore') warnings.warn('noisy library message') warnings.warn('important') [str(w.message) for w in caught]
import warnings with warnings.catch_warnings(record=True) as caught: warnings.simplefilter('always') warnings.filterwarnings('ignore', message='noisy') warnings.warn('noisy library message') warnings.warn('important') [str(w.message) for w in caught]
import warnings warnings.warn('x', 'UserWarning')
import warnings with warnings.catch_warnings(record=True) as caught: warnings.simplefilter('always') warnings.warn('x', UserWarning) len(caught)
import warnings with warnings.catch_warnings(record=True) as caught: warnings.simplefilter('always', UserWarning) warnings.simplefilter('error') warnings.warn('shown, not raised') len(caught)
import warnings with warnings.catch_warnings(record=True) as caught: warnings.simplefilter('error') warnings.simplefilter('always', UserWarning) warnings.warn('shown, not raised') len(caught)
When to use
- Something works but is probably a mistake or will change — the caller should hear about it without crashing
- Library code: deprecations, odd-but-legal arguments, fallbacks that lose performance
- Subclass a category (class ConfigWarning(UserWarning)) so users can filter yours precisely
- The operation cannot continue → raise a real exception
- Diagnostics for operators of a service → logging (logging.captureWarnings(True) routes warnings there)
Notes
FAQ
Run python -W error script.py (or set PYTHONWARNINGS=error), or call warnings.simplefilter('error') — inside warnings.catch_warnings() to limit it to a block. The warning is then raised as an exception of its category and can be caught with except UserWarning, except DeprecationWarning, or except Warning.