python-2.5.2/win32/Lib/warnings.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     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 sys, types
       
     7 import linecache
       
     8 
       
     9 __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
       
    10            "resetwarnings"]
       
    11 
       
    12 # filters contains a sequence of filter 5-tuples
       
    13 # The components of the 5-tuple are:
       
    14 # - an action: error, ignore, always, default, module, or once
       
    15 # - a compiled regex that must match the warning message
       
    16 # - a class representing the warning category
       
    17 # - a compiled regex that must match the module that is being warned
       
    18 # - a line number for the line being warning, or 0 to mean any line
       
    19 # If either if the compiled regexs are None, match anything.
       
    20 filters = []
       
    21 defaultaction = "default"
       
    22 onceregistry = {}
       
    23 
       
    24 def warn(message, category=None, stacklevel=1):
       
    25     """Issue a warning, or maybe ignore it or raise an exception."""
       
    26     # Check if message is already a Warning object
       
    27     if isinstance(message, Warning):
       
    28         category = message.__class__
       
    29     # Check category argument
       
    30     if category is None:
       
    31         category = UserWarning
       
    32     assert issubclass(category, Warning)
       
    33     # Get context information
       
    34     try:
       
    35         caller = sys._getframe(stacklevel)
       
    36     except ValueError:
       
    37         globals = sys.__dict__
       
    38         lineno = 1
       
    39     else:
       
    40         globals = caller.f_globals
       
    41         lineno = caller.f_lineno
       
    42     if '__name__' in globals:
       
    43         module = globals['__name__']
       
    44     else:
       
    45         module = "<string>"
       
    46     filename = globals.get('__file__')
       
    47     if filename:
       
    48         fnl = filename.lower()
       
    49         if fnl.endswith((".pyc", ".pyo")):
       
    50             filename = filename[:-1]
       
    51     else:
       
    52         if module == "__main__":
       
    53             try:
       
    54                 filename = sys.argv[0]
       
    55             except AttributeError:
       
    56                 # embedded interpreters don't have sys.argv, see bug #839151
       
    57                 filename = '__main__'
       
    58         if not filename:
       
    59             filename = module
       
    60     registry = globals.setdefault("__warningregistry__", {})
       
    61     warn_explicit(message, category, filename, lineno, module, registry,
       
    62                   globals)
       
    63 
       
    64 def warn_explicit(message, category, filename, lineno,
       
    65                   module=None, registry=None, module_globals=None):
       
    66     if module is None:
       
    67         module = filename or "<unknown>"
       
    68         if module[-3:].lower() == ".py":
       
    69             module = module[:-3] # XXX What about leading pathname?
       
    70     if registry is None:
       
    71         registry = {}
       
    72     if isinstance(message, Warning):
       
    73         text = str(message)
       
    74         category = message.__class__
       
    75     else:
       
    76         text = message
       
    77         message = category(message)
       
    78     key = (text, category, lineno)
       
    79     # Quick test for common case
       
    80     if registry.get(key):
       
    81         return
       
    82     # Search the filters
       
    83     for item in filters:
       
    84         action, msg, cat, mod, ln = item
       
    85         if ((msg is None or msg.match(text)) and
       
    86             issubclass(category, cat) and
       
    87             (mod is None or mod.match(module)) and
       
    88             (ln == 0 or lineno == ln)):
       
    89             break
       
    90     else:
       
    91         action = defaultaction
       
    92     # Early exit actions
       
    93     if action == "ignore":
       
    94         registry[key] = 1
       
    95         return
       
    96 
       
    97     # Prime the linecache for formatting, in case the
       
    98     # "file" is actually in a zipfile or something.
       
    99     linecache.getlines(filename, module_globals)
       
   100 
       
   101     if action == "error":
       
   102         raise message
       
   103     # Other actions
       
   104     if action == "once":
       
   105         registry[key] = 1
       
   106         oncekey = (text, category)
       
   107         if onceregistry.get(oncekey):
       
   108             return
       
   109         onceregistry[oncekey] = 1
       
   110     elif action == "always":
       
   111         pass
       
   112     elif action == "module":
       
   113         registry[key] = 1
       
   114         altkey = (text, category, 0)
       
   115         if registry.get(altkey):
       
   116             return
       
   117         registry[altkey] = 1
       
   118     elif action == "default":
       
   119         registry[key] = 1
       
   120     else:
       
   121         # Unrecognized actions are errors
       
   122         raise RuntimeError(
       
   123               "Unrecognized action (%r) in warnings.filters:\n %s" %
       
   124               (action, item))
       
   125     # Print message and context
       
   126     showwarning(message, category, filename, lineno)
       
   127 
       
   128 def showwarning(message, category, filename, lineno, file=None):
       
   129     """Hook to write a warning to a file; replace if you like."""
       
   130     if file is None:
       
   131         file = sys.stderr
       
   132     try:
       
   133         file.write(formatwarning(message, category, filename, lineno))
       
   134     except IOError:
       
   135         pass # the file (probably stderr) is invalid - this warning gets lost.
       
   136 
       
   137 def formatwarning(message, category, filename, lineno):
       
   138     """Function to format a warning the standard way."""
       
   139     s =  "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
       
   140     line = linecache.getline(filename, lineno).strip()
       
   141     if line:
       
   142         s = s + "  " + line + "\n"
       
   143     return s
       
   144 
       
   145 def filterwarnings(action, message="", category=Warning, module="", lineno=0,
       
   146                    append=0):
       
   147     """Insert an entry into the list of warnings filters (at the front).
       
   148 
       
   149     Use assertions to check that all arguments have the right type."""
       
   150     import re
       
   151     assert action in ("error", "ignore", "always", "default", "module",
       
   152                       "once"), "invalid action: %r" % (action,)
       
   153     assert isinstance(message, basestring), "message must be a string"
       
   154     assert isinstance(category, (type, types.ClassType)), \
       
   155            "category must be a class"
       
   156     assert issubclass(category, Warning), "category must be a Warning subclass"
       
   157     assert isinstance(module, basestring), "module must be a string"
       
   158     assert isinstance(lineno, int) and lineno >= 0, \
       
   159            "lineno must be an int >= 0"
       
   160     item = (action, re.compile(message, re.I), category,
       
   161             re.compile(module), lineno)
       
   162     if append:
       
   163         filters.append(item)
       
   164     else:
       
   165         filters.insert(0, item)
       
   166 
       
   167 def simplefilter(action, category=Warning, lineno=0, append=0):
       
   168     """Insert a simple entry into the list of warnings filters (at the front).
       
   169 
       
   170     A simple filter matches all modules and messages.
       
   171     """
       
   172     assert action in ("error", "ignore", "always", "default", "module",
       
   173                       "once"), "invalid action: %r" % (action,)
       
   174     assert isinstance(lineno, int) and lineno >= 0, \
       
   175            "lineno must be an int >= 0"
       
   176     item = (action, None, category, None, lineno)
       
   177     if append:
       
   178         filters.append(item)
       
   179     else:
       
   180         filters.insert(0, item)
       
   181 
       
   182 def resetwarnings():
       
   183     """Clear the list of warning filters, so that no filters are active."""
       
   184     filters[:] = []
       
   185 
       
   186 class _OptionError(Exception):
       
   187     """Exception used by option processing helpers."""
       
   188     pass
       
   189 
       
   190 # Helper to process -W options passed via sys.warnoptions
       
   191 def _processoptions(args):
       
   192     for arg in args:
       
   193         try:
       
   194             _setoption(arg)
       
   195         except _OptionError, msg:
       
   196             print >>sys.stderr, "Invalid -W option ignored:", msg
       
   197 
       
   198 # Helper for _processoptions()
       
   199 def _setoption(arg):
       
   200     import re
       
   201     parts = arg.split(':')
       
   202     if len(parts) > 5:
       
   203         raise _OptionError("too many fields (max 5): %r" % (arg,))
       
   204     while len(parts) < 5:
       
   205         parts.append('')
       
   206     action, message, category, module, lineno = [s.strip()
       
   207                                                  for s in parts]
       
   208     action = _getaction(action)
       
   209     message = re.escape(message)
       
   210     category = _getcategory(category)
       
   211     module = re.escape(module)
       
   212     if module:
       
   213         module = module + '$'
       
   214     if lineno:
       
   215         try:
       
   216             lineno = int(lineno)
       
   217             if lineno < 0:
       
   218                 raise ValueError
       
   219         except (ValueError, OverflowError):
       
   220             raise _OptionError("invalid lineno %r" % (lineno,))
       
   221     else:
       
   222         lineno = 0
       
   223     filterwarnings(action, message, category, module, lineno)
       
   224 
       
   225 # Helper for _setoption()
       
   226 def _getaction(action):
       
   227     if not action:
       
   228         return "default"
       
   229     if action == "all": return "always" # Alias
       
   230     for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
       
   231         if a.startswith(action):
       
   232             return a
       
   233     raise _OptionError("invalid action: %r" % (action,))
       
   234 
       
   235 # Helper for _setoption()
       
   236 def _getcategory(category):
       
   237     import re
       
   238     if not category:
       
   239         return Warning
       
   240     if re.match("^[a-zA-Z0-9_]+$", category):
       
   241         try:
       
   242             cat = eval(category)
       
   243         except NameError:
       
   244             raise _OptionError("unknown warning category: %r" % (category,))
       
   245     else:
       
   246         i = category.rfind(".")
       
   247         module = category[:i]
       
   248         klass = category[i+1:]
       
   249         try:
       
   250             m = __import__(module, None, None, [klass])
       
   251         except ImportError:
       
   252             raise _OptionError("invalid module name: %r" % (module,))
       
   253         try:
       
   254             cat = getattr(m, klass)
       
   255         except AttributeError:
       
   256             raise _OptionError("unknown warning category: %r" % (category,))
       
   257     if not issubclass(cat, Warning):
       
   258         raise _OptionError("invalid warning category: %r" % (category,))
       
   259     return cat
       
   260 
       
   261 # Module initialization
       
   262 _processoptions(sys.warnoptions)
       
   263 simplefilter("ignore", category=PendingDeprecationWarning, append=1)
       
   264 simplefilter("ignore", category=ImportWarning, append=1)