diff options
Diffstat (limited to 'Lib/warnings.py')
-rw-r--r-- | Lib/warnings.py | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/Lib/warnings.py b/Lib/warnings.py index edbbb5eda4..70d087e6d9 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -1,12 +1,9 @@ """Python part of the warnings subsystem.""" -# Note: function level imports should *not* be used -# in this module as it may cause import lock deadlock. -# See bug 683658. -import linecache import sys -__all__ = ["warn", "showwarning", "formatwarning", "filterwarnings", +__all__ = ["warn", "warn_explicit", "showwarning", + "formatwarning", "filterwarnings", "simplefilter", "resetwarnings", "catch_warnings"] @@ -14,13 +11,17 @@ def showwarning(message, category, filename, lineno, file=None, line=None): """Hook to write a warning to a file; replace if you like.""" if file is None: file = sys.stderr + if file is None: + # sys.stderr is None when run with pythonw.exe - warnings get lost + return try: file.write(formatwarning(message, category, filename, lineno, line)) - except IOError: + except OSError: pass # the file (probably stderr) is invalid - this warning gets lost. def formatwarning(message, category, filename, lineno, line=None): """Function to format a warning the standard way.""" + import linecache s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message) line = linecache.getline(filename, lineno) if line is None else line if line: @@ -55,6 +56,7 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, filters.append(item) else: filters.insert(0, item) + _filters_mutated() def simplefilter(action, category=Warning, lineno=0, append=False): """Insert a simple entry into the list of warnings filters (at the front). @@ -75,10 +77,12 @@ def simplefilter(action, category=Warning, lineno=0, append=False): filters.append(item) else: filters.insert(0, item) + _filters_mutated() def resetwarnings(): """Clear the list of warning filters, so that no filters are active.""" filters[:] = [] + _filters_mutated() class _OptionError(Exception): """Exception used by option processing helpers.""" @@ -206,6 +210,9 @@ def warn_explicit(message, category, filename, lineno, module = module[:-3] # XXX What about leading pathname? if registry is None: registry = {} + if registry.get('version', 0) != _filters_version: + registry.clear() + registry['version'] = _filters_version if isinstance(message, Warning): text = str(message) category = message.__class__ @@ -233,6 +240,7 @@ def warn_explicit(message, category, filename, lineno, # Prime the linecache for formatting, in case the # "file" is actually in a zipfile or something. + import linecache linecache.getlines(filename, module_globals) if action == "error": @@ -330,6 +338,7 @@ class catch_warnings(object): self._entered = True self._filters = self._module.filters self._module.filters = self._filters[:] + self._module._filters_mutated() self._showwarning = self._module.showwarning if self._record: log = [] @@ -344,6 +353,7 @@ class catch_warnings(object): if not self._entered: raise RuntimeError("Cannot exit %r without entering first" % self) self._module.filters = self._filters + self._module._filters_mutated() self._module.showwarning = self._showwarning @@ -358,15 +368,22 @@ class catch_warnings(object): _warnings_defaults = False try: from _warnings import (filters, _defaultaction, _onceregistry, - warn, warn_explicit) + warn, warn_explicit, _filters_mutated) defaultaction = _defaultaction onceregistry = _onceregistry _warnings_defaults = True + except ImportError: filters = [] defaultaction = "default" onceregistry = {} + _filters_version = 1 + + def _filters_mutated(): + global _filters_version + _filters_version += 1 + # Module initialization _processoptions(sys.warnoptions) |