symbian-qemu-0.9.1-12/python-2.6.1/Lib/warnings.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Python part of the warnings subsystem."""
       
     2 
       
     3 # Note: function level imports should *not* be used
       
     4 # in this module as it may cause import lock deadlock.
       
     5 # See bug 683658.
       
     6 import linecache
       
     7 import sys
       
     8 import types
       
     9 
       
    10 __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
       
    11            "resetwarnings", "catch_warnings"]
       
    12 
       
    13 
       
    14 def warnpy3k(message, category=None, stacklevel=1):
       
    15     """Issue a deprecation warning for Python 3.x related changes.
       
    16 
       
    17     Warnings are omitted unless Python is started with the -3 option.
       
    18     """
       
    19     if sys.py3kwarning:
       
    20         if category is None:
       
    21             category = DeprecationWarning
       
    22         warn(message, category, stacklevel+1)
       
    23 
       
    24 def _show_warning(message, category, filename, lineno, file=None, line=None):
       
    25     """Hook to write a warning to a file; replace if you like."""
       
    26     if file is None:
       
    27         file = sys.stderr
       
    28     try:
       
    29         file.write(formatwarning(message, category, filename, lineno, line))
       
    30     except IOError:
       
    31         pass # the file (probably stderr) is invalid - this warning gets lost.
       
    32 # Keep a worrking version around in case the deprecation of the old API is
       
    33 # triggered.
       
    34 showwarning = _show_warning
       
    35 
       
    36 def formatwarning(message, category, filename, lineno, line=None):
       
    37     """Function to format a warning the standard way."""
       
    38     s =  "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
       
    39     line = linecache.getline(filename, lineno) if line is None else line
       
    40     if line:
       
    41         line = line.strip()
       
    42         s += "  %s\n" % line
       
    43     return s
       
    44 
       
    45 def filterwarnings(action, message="", category=Warning, module="", lineno=0,
       
    46                    append=0):
       
    47     """Insert an entry into the list of warnings filters (at the front).
       
    48 
       
    49     Use assertions to check that all arguments have the right type."""
       
    50     import re
       
    51     assert action in ("error", "ignore", "always", "default", "module",
       
    52                       "once"), "invalid action: %r" % (action,)
       
    53     assert isinstance(message, basestring), "message must be a string"
       
    54     assert isinstance(category, (type, types.ClassType)), \
       
    55            "category must be a class"
       
    56     assert issubclass(category, Warning), "category must be a Warning subclass"
       
    57     assert isinstance(module, basestring), "module must be a string"
       
    58     assert isinstance(lineno, int) and lineno >= 0, \
       
    59            "lineno must be an int >= 0"
       
    60     item = (action, re.compile(message, re.I), category,
       
    61             re.compile(module), lineno)
       
    62     if append:
       
    63         filters.append(item)
       
    64     else:
       
    65         filters.insert(0, item)
       
    66 
       
    67 def simplefilter(action, category=Warning, lineno=0, append=0):
       
    68     """Insert a simple entry into the list of warnings filters (at the front).
       
    69 
       
    70     A simple filter matches all modules and messages.
       
    71     """
       
    72     assert action in ("error", "ignore", "always", "default", "module",
       
    73                       "once"), "invalid action: %r" % (action,)
       
    74     assert isinstance(lineno, int) and lineno >= 0, \
       
    75            "lineno must be an int >= 0"
       
    76     item = (action, None, category, None, lineno)
       
    77     if append:
       
    78         filters.append(item)
       
    79     else:
       
    80         filters.insert(0, item)
       
    81 
       
    82 def resetwarnings():
       
    83     """Clear the list of warning filters, so that no filters are active."""
       
    84     filters[:] = []
       
    85 
       
    86 class _OptionError(Exception):
       
    87     """Exception used by option processing helpers."""
       
    88     pass
       
    89 
       
    90 # Helper to process -W options passed via sys.warnoptions
       
    91 def _processoptions(args):
       
    92     for arg in args:
       
    93         try:
       
    94             _setoption(arg)
       
    95         except _OptionError, msg:
       
    96             print >>sys.stderr, "Invalid -W option ignored:", msg
       
    97 
       
    98 # Helper for _processoptions()
       
    99 def _setoption(arg):
       
   100     import re
       
   101     parts = arg.split(':')
       
   102     if len(parts) > 5:
       
   103         raise _OptionError("too many fields (max 5): %r" % (arg,))
       
   104     while len(parts) < 5:
       
   105         parts.append('')
       
   106     action, message, category, module, lineno = [s.strip()
       
   107                                                  for s in parts]
       
   108     action = _getaction(action)
       
   109     message = re.escape(message)
       
   110     category = _getcategory(category)
       
   111     module = re.escape(module)
       
   112     if module:
       
   113         module = module + '$'
       
   114     if lineno:
       
   115         try:
       
   116             lineno = int(lineno)
       
   117             if lineno < 0:
       
   118                 raise ValueError
       
   119         except (ValueError, OverflowError):
       
   120             raise _OptionError("invalid lineno %r" % (lineno,))
       
   121     else:
       
   122         lineno = 0
       
   123     filterwarnings(action, message, category, module, lineno)
       
   124 
       
   125 # Helper for _setoption()
       
   126 def _getaction(action):
       
   127     if not action:
       
   128         return "default"
       
   129     if action == "all": return "always" # Alias
       
   130     for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
       
   131         if a.startswith(action):
       
   132             return a
       
   133     raise _OptionError("invalid action: %r" % (action,))
       
   134 
       
   135 # Helper for _setoption()
       
   136 def _getcategory(category):
       
   137     import re
       
   138     if not category:
       
   139         return Warning
       
   140     if re.match("^[a-zA-Z0-9_]+$", category):
       
   141         try:
       
   142             cat = eval(category)
       
   143         except NameError:
       
   144             raise _OptionError("unknown warning category: %r" % (category,))
       
   145     else:
       
   146         i = category.rfind(".")
       
   147         module = category[:i]
       
   148         klass = category[i+1:]
       
   149         try:
       
   150             m = __import__(module, None, None, [klass])
       
   151         except ImportError:
       
   152             raise _OptionError("invalid module name: %r" % (module,))
       
   153         try:
       
   154             cat = getattr(m, klass)
       
   155         except AttributeError:
       
   156             raise _OptionError("unknown warning category: %r" % (category,))
       
   157     if not issubclass(cat, Warning):
       
   158         raise _OptionError("invalid warning category: %r" % (category,))
       
   159     return cat
       
   160 
       
   161 
       
   162 # Code typically replaced by _warnings
       
   163 def warn(message, category=None, stacklevel=1):
       
   164     """Issue a warning, or maybe ignore it or raise an exception."""
       
   165     # Check if message is already a Warning object
       
   166     if isinstance(message, Warning):
       
   167         category = message.__class__
       
   168     # Check category argument
       
   169     if category is None:
       
   170         category = UserWarning
       
   171     assert issubclass(category, Warning)
       
   172     # Get context information
       
   173     try:
       
   174         caller = sys._getframe(stacklevel)
       
   175     except ValueError:
       
   176         globals = sys.__dict__
       
   177         lineno = 1
       
   178     else:
       
   179         globals = caller.f_globals
       
   180         lineno = caller.f_lineno
       
   181     if '__name__' in globals:
       
   182         module = globals['__name__']
       
   183     else:
       
   184         module = "<string>"
       
   185     filename = globals.get('__file__')
       
   186     if filename:
       
   187         fnl = filename.lower()
       
   188         if fnl.endswith((".pyc", ".pyo")):
       
   189             filename = filename[:-1]
       
   190     else:
       
   191         if module == "__main__":
       
   192             try:
       
   193                 filename = sys.argv[0]
       
   194             except AttributeError:
       
   195                 # embedded interpreters don't have sys.argv, see bug #839151
       
   196                 filename = '__main__'
       
   197         if not filename:
       
   198             filename = module
       
   199     registry = globals.setdefault("__warningregistry__", {})
       
   200     warn_explicit(message, category, filename, lineno, module, registry,
       
   201                   globals)
       
   202 
       
   203 def warn_explicit(message, category, filename, lineno,
       
   204                   module=None, registry=None, module_globals=None):
       
   205     lineno = int(lineno)
       
   206     if module is None:
       
   207         module = filename or "<unknown>"
       
   208         if module[-3:].lower() == ".py":
       
   209             module = module[:-3] # XXX What about leading pathname?
       
   210     if registry is None:
       
   211         registry = {}
       
   212     if isinstance(message, Warning):
       
   213         text = str(message)
       
   214         category = message.__class__
       
   215     else:
       
   216         text = message
       
   217         message = category(message)
       
   218     key = (text, category, lineno)
       
   219     # Quick test for common case
       
   220     if registry.get(key):
       
   221         return
       
   222     # Search the filters
       
   223     for item in filters:
       
   224         action, msg, cat, mod, ln = item
       
   225         if ((msg is None or msg.match(text)) and
       
   226             issubclass(category, cat) and
       
   227             (mod is None or mod.match(module)) and
       
   228             (ln == 0 or lineno == ln)):
       
   229             break
       
   230     else:
       
   231         action = defaultaction
       
   232     # Early exit actions
       
   233     if action == "ignore":
       
   234         registry[key] = 1
       
   235         return
       
   236 
       
   237     # Prime the linecache for formatting, in case the
       
   238     # "file" is actually in a zipfile or something.
       
   239     linecache.getlines(filename, module_globals)
       
   240 
       
   241     if action == "error":
       
   242         raise message
       
   243     # Other actions
       
   244     if action == "once":
       
   245         registry[key] = 1
       
   246         oncekey = (text, category)
       
   247         if onceregistry.get(oncekey):
       
   248             return
       
   249         onceregistry[oncekey] = 1
       
   250     elif action == "always":
       
   251         pass
       
   252     elif action == "module":
       
   253         registry[key] = 1
       
   254         altkey = (text, category, 0)
       
   255         if registry.get(altkey):
       
   256             return
       
   257         registry[altkey] = 1
       
   258     elif action == "default":
       
   259         registry[key] = 1
       
   260     else:
       
   261         # Unrecognized actions are errors
       
   262         raise RuntimeError(
       
   263               "Unrecognized action (%r) in warnings.filters:\n %s" %
       
   264               (action, item))
       
   265     # Warn if showwarning() does not support the 'line' argument.
       
   266     # Don't use 'inspect' as it relies on an extension module, which break the
       
   267     # build thanks to 'warnings' being imported by setup.py.
       
   268     fxn_code = None
       
   269     if hasattr(showwarning, 'func_code'):
       
   270         fxn_code = showwarning.func_code
       
   271     elif hasattr(showwarning, '__func__'):
       
   272         fxn_code = showwarning.__func__.func_code
       
   273     if fxn_code:
       
   274         args = fxn_code.co_varnames[:fxn_code.co_argcount]
       
   275         CO_VARARGS = 0x4
       
   276         if 'line' not in args and not fxn_code.co_flags & CO_VARARGS:
       
   277             showwarning_msg = ("functions overriding warnings.showwarning() "
       
   278                                 "must support the 'line' argument")
       
   279             if message == showwarning_msg:
       
   280                 _show_warning(message, category, filename, lineno)
       
   281             else:
       
   282                 warn(showwarning_msg, DeprecationWarning)
       
   283     # Print message and context
       
   284     showwarning(message, category, filename, lineno)
       
   285 
       
   286 
       
   287 class WarningMessage(object):
       
   288 
       
   289     """Holds the result of a single showwarning() call."""
       
   290 
       
   291     _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
       
   292                         "line")
       
   293 
       
   294     def __init__(self, message, category, filename, lineno, file=None,
       
   295                     line=None):
       
   296         local_values = locals()
       
   297         for attr in self._WARNING_DETAILS:
       
   298             setattr(self, attr, local_values[attr])
       
   299         self._category_name = category.__name__ if category else None
       
   300 
       
   301     def __str__(self):
       
   302         return ("{message : %r, category : %r, filename : %r, lineno : %s, "
       
   303                     "line : %r}" % (self.message, self._category_name,
       
   304                                     self.filename, self.lineno, self.line))
       
   305 
       
   306 
       
   307 class catch_warnings(object):
       
   308 
       
   309     """A context manager that copies and restores the warnings filter upon
       
   310     exiting the context.
       
   311 
       
   312     The 'record' argument specifies whether warnings should be captured by a
       
   313     custom implementation of warnings.showwarning() and be appended to a list
       
   314     returned by the context manager. Otherwise None is returned by the context
       
   315     manager. The objects appended to the list are arguments whose attributes
       
   316     mirror the arguments to showwarning().
       
   317 
       
   318     The 'module' argument is to specify an alternative module to the module
       
   319     named 'warnings' and imported under that name. This argument is only useful
       
   320     when testing the warnings module itself.
       
   321 
       
   322     """
       
   323 
       
   324     def __init__(self, record=False, module=None):
       
   325         """Specify whether to record warnings and if an alternative module
       
   326         should be used other than sys.modules['warnings'].
       
   327 
       
   328         For compatibility with Python 3.0, please consider all arguments to be
       
   329         keyword-only.
       
   330 
       
   331         """
       
   332         self._record = record
       
   333         self._module = sys.modules['warnings'] if module is None else module
       
   334         self._entered = False
       
   335 
       
   336     def __repr__(self):
       
   337         args = []
       
   338         if self._record:
       
   339             args.append("record=True")
       
   340         if self._module is not sys.modules['warnings']:
       
   341             args.append("module=%r" % self._module)
       
   342         name = type(self).__name__
       
   343         return "%s(%s)" % (name, ", ".join(args))
       
   344 
       
   345     def __enter__(self):
       
   346         if self._entered:
       
   347             raise RuntimeError("Cannot enter %r twice" % self)
       
   348         self._entered = True
       
   349         self._filters = self._module.filters
       
   350         self._module.filters = self._filters[:]
       
   351         self._showwarning = self._module.showwarning
       
   352         if self._record:
       
   353             log = []
       
   354             def showwarning(*args, **kwargs):
       
   355                 log.append(WarningMessage(*args, **kwargs))
       
   356             self._module.showwarning = showwarning
       
   357             return log
       
   358         else:
       
   359             return None
       
   360 
       
   361     def __exit__(self, *exc_info):
       
   362         if not self._entered:
       
   363             raise RuntimeError("Cannot exit %r without entering first" % self)
       
   364         self._module.filters = self._filters
       
   365         self._module.showwarning = self._showwarning
       
   366 
       
   367 
       
   368 # filters contains a sequence of filter 5-tuples
       
   369 # The components of the 5-tuple are:
       
   370 # - an action: error, ignore, always, default, module, or once
       
   371 # - a compiled regex that must match the warning message
       
   372 # - a class representing the warning category
       
   373 # - a compiled regex that must match the module that is being warned
       
   374 # - a line number for the line being warning, or 0 to mean any line
       
   375 # If either if the compiled regexs are None, match anything.
       
   376 _warnings_defaults = False
       
   377 try:
       
   378     from _warnings import (filters, default_action, once_registry,
       
   379                             warn, warn_explicit)
       
   380     defaultaction = default_action
       
   381     onceregistry = once_registry
       
   382     _warnings_defaults = True
       
   383 except ImportError:
       
   384     filters = []
       
   385     defaultaction = "default"
       
   386     onceregistry = {}
       
   387 
       
   388 
       
   389 # Module initialization
       
   390 _processoptions(sys.warnoptions)
       
   391 if not _warnings_defaults:
       
   392     simplefilter("ignore", category=PendingDeprecationWarning, append=1)
       
   393     simplefilter("ignore", category=ImportWarning, append=1)
       
   394     bytes_warning = sys.flags.bytes_warning
       
   395     if bytes_warning > 1:
       
   396         bytes_action = "error"
       
   397     elif bytes_warning:
       
   398         bytes_action = "default"
       
   399     else:
       
   400         bytes_action = "ignore"
       
   401     simplefilter(bytes_action, category=BytesWarning, append=1)
       
   402 del _warnings_defaults