diff options
-rw-r--r-- | Lib/test/output/test_warnings | 10 | ||||
-rw-r--r-- | Lib/test/test_warnings.py | 53 | ||||
-rw-r--r-- | Lib/warnings.py | 71 |
3 files changed, 91 insertions, 43 deletions
diff --git a/Lib/test/output/test_warnings b/Lib/test/output/test_warnings new file mode 100644 index 0000000..9b45e42 --- /dev/null +++ b/Lib/test/output/test_warnings @@ -0,0 +1,10 @@ +test_warnings +('ignore', False, 'FutureWarning', False, 0) +('ignore', True, 'OverflowWarning', True, 0) +('ignore', True, 'PendingDeprecationWarning', True, 0) +Lib/test/test_warnings.py:31: UserWarning: hello world +Lib/test/test_warnings.py:32: UserWarning: hello world +Lib/test/test_warnings.py:33: DeprecationWarning: hello world +Lib/test/test_warnings.py:35: UserWarning: hello world +Caught UserWarning: hello world +Caught AssertionError: invalid action: 'booh' diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py new file mode 100644 index 0000000..9cd3c30 --- /dev/null +++ b/Lib/test/test_warnings.py @@ -0,0 +1,53 @@ +import warnings + +# The warnings module isn't easily tested, because it relies on module +# globals to store configuration information. We need to extract the +# current settings to avoid bashing them while running tests. + +_filters = [] +_showwarning = None + +def showwarning(message, category, filename, lineno, file=None): + i = filename.find("Lib/") + filename = filename[i:] + print "%s:%s: %s: %s" % (filename, lineno, category.__name__, message) + +def monkey(): + global _filters, _showwarning + _filters = warnings.filters[:] + _showwarning = warnings.showwarning + warnings.showwarning = showwarning + +def unmonkey(): + warnings.filters = _filters[:] + warnings.showwarning = _showwarning + +def test(): + for item in warnings.filters: + print (item[0], item[1] is None, item[2].__name__, item[3] is None, + item[4]) + hello = "hello world" + for i in range(4): + warnings.warn(hello) + warnings.warn(hello, UserWarning) + warnings.warn(hello, DeprecationWarning) + for i in range(3): + warnings.warn(hello) + warnings.filterwarnings("error", "", Warning, "", 0) + try: + warnings.warn(hello) + except Exception, msg: + print "Caught", msg.__class__.__name__ + ":", msg + else: + print "No exception" + warnings.resetwarnings() + try: + warnings.filterwarnings("booh", "", Warning, "", 0) + except Exception, msg: + print "Caught", msg.__class__.__name__ + ":", msg + else: + print "No exception" + +monkey() +test() +unmonkey() diff --git a/Lib/warnings.py b/Lib/warnings.py index 1c55fb2..c2bc06e 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -9,8 +9,16 @@ import linecache __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings", "resetwarnings"] -defaultaction = "default" +# filters contains a sequence of filter 5-tuples +# The components of the 5-tuple are: +# - an action: error, ignore, always, default, module, or once +# - a compiled regex that must match the warning message +# - a class representing the warning category +# - a compiled regex that must match the module that is being warned +# - a line number for the line being warning, or 0 to mean any line +# If either if the compiled regexs are None, match anything. filters = [] +defaultaction = "default" onceregistry = {} def warn(message, category=None, stacklevel=1): @@ -69,9 +77,9 @@ def warn_explicit(message, category, filename, lineno, # Search the filters for item in filters: action, msg, cat, mod, ln = item - if (msg.match(text) and + if ((msg is None or msg.match(text)) and issubclass(category, cat) and - mod.match(module) and + (msg is None or mod.match(module)) and (ln == 0 or lineno == ln)): break else: @@ -145,6 +153,21 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, else: filters.insert(0, item) +def simplefilter(action, category=Warning, lineno=0, append=0): + """Insert a simple entry into the list of warnings filters (at the front). + + A simple filter matches all modules and messages. + """ + assert action in ("error", "ignore", "always", "default", "module", + "once"), "invalid action: %s" % `action` + assert isinstance(lineno, int) and lineno >= 0, \ + "lineno must be an int >= 0" + item = (action, None, category, None, lineno) + if append: + filters.append(item) + else: + filters.insert(0, item) + def resetwarnings(): """Clear the list of warning filters, so that no filters are active.""" filters[:] = [] @@ -225,44 +248,6 @@ def _getcategory(category): raise _OptionError("invalid warning category: %s" % `category`) return cat -# Self-test -def _test(): - import getopt - testoptions = [] - try: - opts, args = getopt.getopt(sys.argv[1:], "W:") - except getopt.error, msg: - print >>sys.stderr, msg - return - for o, a in opts: - testoptions.append(a) - try: - _processoptions(testoptions) - except _OptionError, msg: - print >>sys.stderr, msg - return - for item in filters: print item - hello = "hello world" - warn(hello); warn(hello); warn(hello); warn(hello) - warn(hello, UserWarning) - warn(hello, DeprecationWarning) - for i in range(3): - warn(hello) - filterwarnings("error", "", Warning, "", 0) - try: - warn(hello) - except Exception, msg: - print "Caught", msg.__class__.__name__ + ":", msg - else: - print "No exception" - resetwarnings() - try: - filterwarnings("booh", "", Warning, "", 0) - except Exception, msg: - print "Caught", msg.__class__.__name__ + ":", msg - else: - print "No exception" - # Module initialization if __name__ == "__main__": import __main__ @@ -270,5 +255,5 @@ if __name__ == "__main__": _test() else: _processoptions(sys.warnoptions) - filterwarnings("ignore", category=OverflowWarning, append=1) - filterwarnings("ignore", category=PendingDeprecationWarning, append=1) + simplefilter("ignore", category=OverflowWarning, append=1) + simplefilter("ignore", category=PendingDeprecationWarning, append=1) |