In addition to pre-existing warning categories, users can define their own warning classes, such as in the code below:
$ cat mwe.py
#!/usr/bin/env python3.5
import warnings
import pprint
class ObnoxiousWarning(UserWarning):
pass
for i in range(3):
print(i)
warnings.warn("I don't like this.", ObnoxiousWarning)
When invoking Python, the -W
flag controls how to filter warnings. But when I try to get it to ignore my freshly minted warning category, I'm told the filter is ignored:
$ python3.5 -W ignore::ObnoxiousWarning ./mwe.py
Invalid -W option ignored: unknown warning category: 'ObnoxiousWarning'
0
./mwe.py:11: ObnoxiousWarning: I don't like this.
warnings.warn("I don't like this.", ObnoxiousWarning)
1
2
How can I use the commandline to insert a filter for custom warning categories (as opposed to all UserWarnings or filtering based on the warning message, which I can do)?
Edit 2018-11-29: See Issue 22543: -W option cannot use nonstandard categories
Use the filterwarnings() Function to Suppress Warnings in Python. The warnings module handles warnings in Python. We can show warnings raised by the user with the warn() function. We can use the filterwarnings() function to perform actions on specific warnings.
DeprecationWarning. Base category for warnings about deprecated features when those warnings are intended for other Python developers (ignored by default, unless triggered by code in __main__ ).
A RuntimeWarning is used to signal to the runtime framework that a non-fatal error has been encountered. Server startup will proceed as usual.
showwarning(message, category, filename, lineno, file=None, line=None): This function Writes a warning to a file. simplefilter(action, category=Warning, lineno=0, append=False): This function adds a single entry into the warnings filter requirements list.
Some of the answers lie in python source code. Look at the _getcategory function: https://github.com/python/cpython/blob/3.5/Lib/warnings.py#L147
def _getcategory(category):
import re
if not category:
return Warning
if re.match("^[a-zA-Z0-9_]+$", category):
try:
cat = eval(category)
except NameError:
raise _OptionError("unknown warning category: %r" % (category,))
else:
i = category.rfind(".")
module = category[:i]
klass = category[i+1:]
try:
m = __import__(module, None, None, [klass])
except ImportError:
raise _OptionError("invalid module name: %r" % (module,))
try:
cat = getattr(m, klass)
except AttributeError:
raise _OptionError("unknown warning category: %r" % (category,))
if not issubclass(cat, Warning):
raise _OptionError("invalid warning category: %r" % (category,))
return cat
Python tries to eval your category or to import it from module you specify in filter. And that will fail, unless you have your module in PYTHONPATH.
PYTHONPATH='<path_to_dir_where_mwe_located>' python -W ignore::mwe.ObnoxiousWarning
This way, if you import your module in python shell warning would be filtered as you wish. To use filter in commandline, you must define your warning in separate module, other than that you execute.
mwe.py
class ObnoxiousWarning(UserWarning):
pass
entrypoint.py
#!/usr/bin/env python3.5
import warnings
import pprint
from mwe import ObnoxiousWarning
for i in range(3):
print(i)
warnings.warn("I don't like this.", ObnoxiousWarning)
And finally:
PYTHONPATH='<path_to_dir_where_mwe_located>' python -W ignore::mwe.ObnoxiousWarning ./entrypoint.py
0
1
2
I don't understand why defining separate module with warning works, but it is. May be someone will explain it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With