diff options
Diffstat (limited to 'Lib/warnings.py')
| -rw-r--r-- | Lib/warnings.py | 271 | 
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  | 
