+++ /dev/null
-"""Python part of the warnings subsystem."""\r
-\r
-# Note: function level imports should *not* be used\r
-# in this module as it may cause import lock deadlock.\r
-# See bug 683658.\r
-import linecache\r
-import sys\r
-import types\r
-\r
-__all__ = ["warn", "warn_explicit", "showwarning",\r
- "formatwarning", "filterwarnings", "simplefilter",\r
- "resetwarnings", "catch_warnings"]\r
-\r
-\r
-def warnpy3k(message, category=None, stacklevel=1):\r
- """Issue a deprecation warning for Python 3.x related changes.\r
-\r
- Warnings are omitted unless Python is started with the -3 option.\r
- """\r
- if sys.py3kwarning:\r
- if category is None:\r
- category = DeprecationWarning\r
- warn(message, category, stacklevel+1)\r
-\r
-def _show_warning(message, category, filename, lineno, file=None, line=None):\r
- """Hook to write a warning to a file; replace if you like."""\r
- if file is None:\r
- file = sys.stderr\r
- if file is None:\r
- # sys.stderr is None - warnings get lost\r
- return\r
- try:\r
- file.write(formatwarning(message, category, filename, lineno, line))\r
- except IOError:\r
- pass # the file (probably stderr) is invalid - this warning gets lost.\r
-# Keep a working version around in case the deprecation of the old API is\r
-# triggered.\r
-showwarning = _show_warning\r
-\r
-def formatwarning(message, category, filename, lineno, line=None):\r
- """Function to format a warning the standard way."""\r
- s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)\r
- line = linecache.getline(filename, lineno) if line is None else line\r
- if line:\r
- line = line.strip()\r
- s += " %s\n" % line\r
- return s\r
-\r
-def filterwarnings(action, message="", category=Warning, module="", lineno=0,\r
- append=0):\r
- """Insert an entry into the list of warnings filters (at the front).\r
-\r
- 'action' -- one of "error", "ignore", "always", "default", "module",\r
- or "once"\r
- 'message' -- a regex that the warning message must match\r
- 'category' -- a class that the warning must be a subclass of\r
- 'module' -- a regex that the module name must match\r
- 'lineno' -- an integer line number, 0 matches all warnings\r
- 'append' -- if true, append to the list of filters\r
- """\r
- import re\r
- assert action in ("error", "ignore", "always", "default", "module",\r
- "once"), "invalid action: %r" % (action,)\r
- assert isinstance(message, basestring), "message must be a string"\r
- assert isinstance(category, (type, types.ClassType)), \\r
- "category must be a class"\r
- assert issubclass(category, Warning), "category must be a Warning subclass"\r
- assert isinstance(module, basestring), "module must be a string"\r
- assert isinstance(lineno, int) and lineno >= 0, \\r
- "lineno must be an int >= 0"\r
- item = (action, re.compile(message, re.I), category,\r
- re.compile(module), lineno)\r
- if append:\r
- filters.append(item)\r
- else:\r
- filters.insert(0, item)\r
-\r
-def simplefilter(action, category=Warning, lineno=0, append=0):\r
- """Insert a simple entry into the list of warnings filters (at the front).\r
-\r
- A simple filter matches all modules and messages.\r
- 'action' -- one of "error", "ignore", "always", "default", "module",\r
- or "once"\r
- 'category' -- a class that the warning must be a subclass of\r
- 'lineno' -- an integer line number, 0 matches all warnings\r
- 'append' -- if true, append to the list of filters\r
- """\r
- assert action in ("error", "ignore", "always", "default", "module",\r
- "once"), "invalid action: %r" % (action,)\r
- assert isinstance(lineno, int) and lineno >= 0, \\r
- "lineno must be an int >= 0"\r
- item = (action, None, category, None, lineno)\r
- if append:\r
- filters.append(item)\r
- else:\r
- filters.insert(0, item)\r
-\r
-def resetwarnings():\r
- """Clear the list of warning filters, so that no filters are active."""\r
- filters[:] = []\r
-\r
-class _OptionError(Exception):\r
- """Exception used by option processing helpers."""\r
- pass\r
-\r
-# Helper to process -W options passed via sys.warnoptions\r
-def _processoptions(args):\r
- for arg in args:\r
- try:\r
- _setoption(arg)\r
- except _OptionError, msg:\r
- print >>sys.stderr, "Invalid -W option ignored:", msg\r
-\r
-# Helper for _processoptions()\r
-def _setoption(arg):\r
- import re\r
- parts = arg.split(':')\r
- if len(parts) > 5:\r
- raise _OptionError("too many fields (max 5): %r" % (arg,))\r
- while len(parts) < 5:\r
- parts.append('')\r
- action, message, category, module, lineno = [s.strip()\r
- for s in parts]\r
- action = _getaction(action)\r
- message = re.escape(message)\r
- category = _getcategory(category)\r
- module = re.escape(module)\r
- if module:\r
- module = module + '$'\r
- if lineno:\r
- try:\r
- lineno = int(lineno)\r
- if lineno < 0:\r
- raise ValueError\r
- except (ValueError, OverflowError):\r
- raise _OptionError("invalid lineno %r" % (lineno,))\r
- else:\r
- lineno = 0\r
- filterwarnings(action, message, category, module, lineno)\r
-\r
-# Helper for _setoption()\r
-def _getaction(action):\r
- if not action:\r
- return "default"\r
- if action == "all": return "always" # Alias\r
- for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):\r
- if a.startswith(action):\r
- return a\r
- raise _OptionError("invalid action: %r" % (action,))\r
-\r
-# Helper for _setoption()\r
-def _getcategory(category):\r
- import re\r
- if not category:\r
- return Warning\r
- if re.match("^[a-zA-Z0-9_]+$", category):\r
- try:\r
- cat = eval(category)\r
- except NameError:\r
- raise _OptionError("unknown warning category: %r" % (category,))\r
- else:\r
- i = category.rfind(".")\r
- module = category[:i]\r
- klass = category[i+1:]\r
- try:\r
- m = __import__(module, None, None, [klass])\r
- except ImportError:\r
- raise _OptionError("invalid module name: %r" % (module,))\r
- try:\r
- cat = getattr(m, klass)\r
- except AttributeError:\r
- raise _OptionError("unknown warning category: %r" % (category,))\r
- if not issubclass(cat, Warning):\r
- raise _OptionError("invalid warning category: %r" % (category,))\r
- return cat\r
-\r
-\r
-# Code typically replaced by _warnings\r
-def warn(message, category=None, stacklevel=1):\r
- """Issue a warning, or maybe ignore it or raise an exception."""\r
- # Check if message is already a Warning object\r
- if isinstance(message, Warning):\r
- category = message.__class__\r
- # Check category argument\r
- if category is None:\r
- category = UserWarning\r
- assert issubclass(category, Warning)\r
- # Get context information\r
- try:\r
- caller = sys._getframe(stacklevel)\r
- except ValueError:\r
- globals = sys.__dict__\r
- lineno = 1\r
- else:\r
- globals = caller.f_globals\r
- lineno = caller.f_lineno\r
- if '__name__' in globals:\r
- module = globals['__name__']\r
- else:\r
- module = "<string>"\r
- filename = globals.get('__file__')\r
- if filename:\r
- fnl = filename.lower()\r
- if fnl.endswith((".pyc", ".pyo")):\r
- filename = filename[:-1]\r
- else:\r
- if module == "__main__":\r
- try:\r
- filename = sys.argv[0]\r
- except AttributeError:\r
- # embedded interpreters don't have sys.argv, see bug #839151\r
- filename = '__main__'\r
- if not filename:\r
- filename = module\r
- registry = globals.setdefault("__warningregistry__", {})\r
- warn_explicit(message, category, filename, lineno, module, registry,\r
- globals)\r
-\r
-def warn_explicit(message, category, filename, lineno,\r
- module=None, registry=None, module_globals=None):\r
- lineno = int(lineno)\r
- if module is None:\r
- module = filename or "<unknown>"\r
- if module[-3:].lower() == ".py":\r
- module = module[:-3] # XXX What about leading pathname?\r
- if registry is None:\r
- registry = {}\r
- if isinstance(message, Warning):\r
- text = str(message)\r
- category = message.__class__\r
- else:\r
- text = message\r
- message = category(message)\r
- key = (text, category, lineno)\r
- # Quick test for common case\r
- if registry.get(key):\r
- return\r
- # Search the filters\r
- for item in filters:\r
- action, msg, cat, mod, ln = item\r
- if ((msg is None or msg.match(text)) and\r
- issubclass(category, cat) and\r
- (mod is None or mod.match(module)) and\r
- (ln == 0 or lineno == ln)):\r
- break\r
- else:\r
- action = defaultaction\r
- # Early exit actions\r
- if action == "ignore":\r
- registry[key] = 1\r
- return\r
-\r
- # Prime the linecache for formatting, in case the\r
- # "file" is actually in a zipfile or something.\r
- linecache.getlines(filename, module_globals)\r
-\r
- if action == "error":\r
- raise message\r
- # Other actions\r
- if action == "once":\r
- registry[key] = 1\r
- oncekey = (text, category)\r
- if onceregistry.get(oncekey):\r
- return\r
- onceregistry[oncekey] = 1\r
- elif action == "always":\r
- pass\r
- elif action == "module":\r
- registry[key] = 1\r
- altkey = (text, category, 0)\r
- if registry.get(altkey):\r
- return\r
- registry[altkey] = 1\r
- elif action == "default":\r
- registry[key] = 1\r
- else:\r
- # Unrecognized actions are errors\r
- raise RuntimeError(\r
- "Unrecognized action (%r) in warnings.filters:\n %s" %\r
- (action, item))\r
- # Print message and context\r
- showwarning(message, category, filename, lineno)\r
-\r
-\r
-class WarningMessage(object):\r
-\r
- """Holds the result of a single showwarning() call."""\r
-\r
- _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",\r
- "line")\r
-\r
- def __init__(self, message, category, filename, lineno, file=None,\r
- line=None):\r
- local_values = locals()\r
- for attr in self._WARNING_DETAILS:\r
- setattr(self, attr, local_values[attr])\r
- self._category_name = category.__name__ if category else None\r
-\r
- def __str__(self):\r
- return ("{message : %r, category : %r, filename : %r, lineno : %s, "\r
- "line : %r}" % (self.message, self._category_name,\r
- self.filename, self.lineno, self.line))\r
-\r
-\r
-class catch_warnings(object):\r
-\r
- """A context manager that copies and restores the warnings filter upon\r
- exiting the context.\r
-\r
- The 'record' argument specifies whether warnings should be captured by a\r
- custom implementation of warnings.showwarning() and be appended to a list\r
- returned by the context manager. Otherwise None is returned by the context\r
- manager. The objects appended to the list are arguments whose attributes\r
- mirror the arguments to showwarning().\r
-\r
- The 'module' argument is to specify an alternative module to the module\r
- named 'warnings' and imported under that name. This argument is only useful\r
- when testing the warnings module itself.\r
-\r
- """\r
-\r
- def __init__(self, record=False, module=None):\r
- """Specify whether to record warnings and if an alternative module\r
- should be used other than sys.modules['warnings'].\r
-\r
- For compatibility with Python 3.0, please consider all arguments to be\r
- keyword-only.\r
-\r
- """\r
- self._record = record\r
- self._module = sys.modules['warnings'] if module is None else module\r
- self._entered = False\r
-\r
- def __repr__(self):\r
- args = []\r
- if self._record:\r
- args.append("record=True")\r
- if self._module is not sys.modules['warnings']:\r
- args.append("module=%r" % self._module)\r
- name = type(self).__name__\r
- return "%s(%s)" % (name, ", ".join(args))\r
-\r
- def __enter__(self):\r
- if self._entered:\r
- raise RuntimeError("Cannot enter %r twice" % self)\r
- self._entered = True\r
- self._filters = self._module.filters\r
- self._module.filters = self._filters[:]\r
- self._showwarning = self._module.showwarning\r
- if self._record:\r
- log = []\r
- def showwarning(*args, **kwargs):\r
- log.append(WarningMessage(*args, **kwargs))\r
- self._module.showwarning = showwarning\r
- return log\r
- else:\r
- return None\r
-\r
- def __exit__(self, *exc_info):\r
- if not self._entered:\r
- raise RuntimeError("Cannot exit %r without entering first" % self)\r
- self._module.filters = self._filters\r
- self._module.showwarning = self._showwarning\r
-\r
-\r
-# filters contains a sequence of filter 5-tuples\r
-# The components of the 5-tuple are:\r
-# - an action: error, ignore, always, default, module, or once\r
-# - a compiled regex that must match the warning message\r
-# - a class representing the warning category\r
-# - a compiled regex that must match the module that is being warned\r
-# - a line number for the line being warning, or 0 to mean any line\r
-# If either if the compiled regexs are None, match anything.\r
-_warnings_defaults = False\r
-try:\r
- from _warnings import (filters, default_action, once_registry,\r
- warn, warn_explicit)\r
- defaultaction = default_action\r
- onceregistry = once_registry\r
- _warnings_defaults = True\r
-except ImportError:\r
- filters = []\r
- defaultaction = "default"\r
- onceregistry = {}\r
-\r
-\r
-# Module initialization\r
-_processoptions(sys.warnoptions)\r
-if not _warnings_defaults:\r
- silence = [ImportWarning, PendingDeprecationWarning]\r
- # Don't silence DeprecationWarning if -3 or -Q was used.\r
- if not sys.py3kwarning and not sys.flags.division_warning:\r
- silence.append(DeprecationWarning)\r
- for cls in silence:\r
- simplefilter("ignore", category=cls)\r
- bytes_warning = sys.flags.bytes_warning\r
- if bytes_warning > 1:\r
- bytes_action = "error"\r
- elif bytes_warning:\r
- bytes_action = "default"\r
- else:\r
- bytes_action = "ignore"\r
- simplefilter(bytes_action, category=BytesWarning, append=1)\r
-del _warnings_defaults\r