summaryrefslogtreecommitdiffstats
path: root/Lib/warnings.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/warnings.py')
-rw-r--r--Lib/warnings.py271
1 files changed, 148 insertions, 123 deletions
diff --git a/Lib/warnings.py b/Lib/warnings.py
index 40079ba..c95ffc3 100644
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -3,143 +3,30 @@
# Note: function level imports should *not* be used
# in this module as it may cause import lock deadlock.
# See bug 683658.
-import sys
import linecache
+import sys
+import types
__all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
"resetwarnings"]
-# 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):
- """Issue a warning, or maybe ignore it or raise an exception."""
- # Check if message is already a Warning object
- if isinstance(message, Warning):
- category = message.__class__
- # Check category argument
- if category is None:
- category = UserWarning
- assert issubclass(category, Warning)
- # Get context information
- try:
- caller = sys._getframe(stacklevel)
- except ValueError:
- globals = sys.__dict__
- lineno = 1
- else:
- globals = caller.f_globals
- lineno = caller.f_lineno
- if '__name__' in globals:
- module = globals['__name__']
- else:
- module = "<string>"
- filename = globals.get('__file__')
- if filename:
- fnl = filename.lower()
- if fnl.endswith((".pyc", ".pyo")):
- filename = filename[:-1]
- else:
- if module == "__main__":
- try:
- filename = sys.argv[0]
- except AttributeError:
- # embedded interpreters don't have sys.argv, see bug #839151
- filename = '__main__'
- if not filename:
- filename = module
- registry = globals.setdefault("__warningregistry__", {})
- warn_explicit(message, category, filename, lineno, module, registry,
- globals)
-
-def warn_explicit(message, category, filename, lineno,
- module=None, registry=None, module_globals=None):
- if module is None:
- module = filename or "<unknown>"
- if module[-3:].lower() == ".py":
- module = module[:-3] # XXX What about leading pathname?
- if registry is None:
- registry = {}
- if isinstance(message, Warning):
- text = str(message)
- category = message.__class__
- else:
- text = message
- message = category(message)
- key = (text, category, lineno)
- # Quick test for common case
- if registry.get(key):
- return
- # Search the filters
- for item in filters:
- action, msg, cat, mod, ln = item
- if ((msg is None or msg.match(text)) and
- issubclass(category, cat) and
- (mod is None or mod.match(module)) and
- (ln == 0 or lineno == ln)):
- break
- else:
- action = defaultaction
- # Early exit actions
- if action == "ignore":
- registry[key] = 1
- return
-
- # Prime the linecache for formatting, in case the
- # "file" is actually in a zipfile or something.
- linecache.getlines(filename, module_globals)
-
- if action == "error":
- raise message
- # Other actions
- if action == "once":
- registry[key] = 1
- oncekey = (text, category)
- if onceregistry.get(oncekey):
- return
- onceregistry[oncekey] = 1
- elif action == "always":
- pass
- elif action == "module":
- registry[key] = 1
- altkey = (text, category, 0)
- if registry.get(altkey):
- return
- registry[altkey] = 1
- elif action == "default":
- registry[key] = 1
- else:
- # Unrecognized actions are errors
- raise RuntimeError(
- "Unrecognized action (%r) in warnings.filters:\n %s" %
- (action, item))
- # Print message and context
- showwarning(message, category, filename, lineno)
-def showwarning(message, category, filename, lineno, file=None):
+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
try:
- file.write(formatwarning(message, category, filename, lineno))
+ file.write(formatwarning(message, category, filename, lineno, line))
except IOError:
pass # the file (probably stderr) is invalid - this warning gets lost.
-def formatwarning(message, category, filename, lineno):
+def formatwarning(message, category, filename, lineno, line=None):
"""Function to format a warning the standard way."""
s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
- line = linecache.getline(filename, lineno).strip()
+ line = linecache.getline(filename, lineno) if line is None else line
if line:
- s = s + " " + line + "\n"
+ line = line.strip()
+ s += " %s\n" % line
return s
def filterwarnings(action, message="", category=Warning, module="", lineno=0,
@@ -257,7 +144,145 @@ def _getcategory(category):
raise _OptionError("invalid warning category: %r" % (category,))
return cat
+
+# Code typically replaced by _warnings
+def warn(message, category=None, stacklevel=1):
+ """Issue a warning, or maybe ignore it or raise an exception."""
+ # Check if message is already a Warning object
+ if isinstance(message, Warning):
+ category = message.__class__
+ # Check category argument
+ if category is None:
+ category = UserWarning
+ assert issubclass(category, Warning)
+ # Get context information
+ try:
+ caller = sys._getframe(stacklevel)
+ except ValueError:
+ globals = sys.__dict__
+ lineno = 1
+ else:
+ globals = caller.f_globals
+ lineno = caller.f_lineno
+ if '__name__' in globals:
+ module = globals['__name__']
+ else:
+ module = "<string>"
+ filename = globals.get('__file__')
+ if filename:
+ fnl = filename.lower()
+ if fnl.endswith((".pyc", ".pyo")):
+ filename = filename[:-1]
+ else:
+ if module == "__main__":
+ try:
+ filename = sys.argv[0]
+ except AttributeError:
+ # embedded interpreters don't have sys.argv, see bug #839151
+ filename = '__main__'
+ if not filename:
+ filename = module
+ registry = globals.setdefault("__warningregistry__", {})
+ warn_explicit(message, category, filename, lineno, module, registry,
+ globals)
+
+def warn_explicit(message, category, filename, lineno,
+ module=None, registry=None, module_globals=None):
+ if module is None:
+ module = filename or "<unknown>"
+ if module[-3:].lower() == ".py":
+ module = module[:-3] # XXX What about leading pathname?
+ if registry is None:
+ registry = {}
+ if isinstance(message, Warning):
+ text = str(message)
+ category = message.__class__
+ else:
+ text = message
+ message = category(message)
+ key = (text, category, lineno)
+ # Quick test for common case
+ if registry.get(key):
+ return
+ # Search the filters
+ for item in filters:
+ action, msg, cat, mod, ln = item
+ if ((msg is None or msg.match(text)) and
+ issubclass(category, cat) and
+ (mod is None or mod.match(module)) and
+ (ln == 0 or lineno == ln)):
+ break
+ else:
+ action = defaultaction
+ # Early exit actions
+ if action == "ignore":
+ registry[key] = 1
+ return
+
+ # Prime the linecache for formatting, in case the
+ # "file" is actually in a zipfile or something.
+ linecache.getlines(filename, module_globals)
+
+ if action == "error":
+ raise message
+ # Other actions
+ if action == "once":
+ registry[key] = 1
+ oncekey = (text, category)
+ if onceregistry.get(oncekey):
+ return
+ onceregistry[oncekey] = 1
+ elif action == "always":
+ pass
+ elif action == "module":
+ registry[key] = 1
+ altkey = (text, category, 0)
+ if registry.get(altkey):
+ return
+ registry[altkey] = 1
+ elif action == "default":
+ registry[key] = 1
+ else:
+ # Unrecognized actions are errors
+ raise RuntimeError(
+ "Unrecognized action (%r) in warnings.filters:\n %s" %
+ (action, item))
+ # Print message and context
+ showwarning(message, category, filename, lineno)
+
+
+# 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.
+_warnings_defaults = False
+try:
+ from _warnings import (filters, default_action, once_registry,
+ warn, warn_explicit)
+ defaultaction = default_action
+ onceregistry = once_registry
+ _warnings_defaults = True
+except ImportError:
+ filters = []
+ defaultaction = "default"
+ onceregistry = {}
+
+
# Module initialization
_processoptions(sys.warnoptions)
-simplefilter("ignore", category=PendingDeprecationWarning, append=1)
-simplefilter("ignore", category=ImportWarning, append=1)
+if not _warnings_defaults:
+ simplefilter("ignore", category=PendingDeprecationWarning, append=1)
+ simplefilter("ignore", category=ImportWarning, append=1)
+ bytes_warning = sys.flags.bytes_warning
+ if bytes_warning > 1:
+ bytes_action = "error"
+ elif bytes_warning:
+ bytes_action = "default"
+ else:
+ bytes_action = "ignore"
+ simplefilter(bytes_action, category=BytesWarning, append=1)
+del _warnings_defaults