0001 """Python part of the warnings subsystem.""" 0002 0003 # Note: function level imports should *not* be used 0004 # in this module as it may cause import lock deadlock. 0005 # See bug 683658. 0006 import sys, types 0007 import linecache 0008 0009 __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings", 0010 "resetwarnings"] 0011 0012 # filters contains a sequence of filter 5-tuples 0013 # The components of the 5-tuple are: 0014 # - an action: error, ignore, always, default, module, or once 0015 # - a compiled regex that must match the warning message 0016 # - a class representing the warning category 0017 # - a compiled regex that must match the module that is being warned 0018 # - a line number for the line being warning, or 0 to mean any line 0019 # If either if the compiled regexs are None, match anything. 0020 filters = [] 0021 defaultaction = "default" 0022 onceregistry = {} 0023 0024 def warn(message, category=None, stacklevel=1): 0025 """Issue a warning, or maybe ignore it or raise an exception.""" 0026 # Check if message is already a Warning object 0027 if isinstance(message, Warning): 0028 category = message.__class__ 0029 # Check category argument 0030 if category is None: 0031 category = UserWarning 0032 assert issubclass(category, Warning) 0033 # Get context information 0034 try: 0035 caller = sys._getframe(stacklevel) 0036 except ValueError: 0037 globals = sys.__dict__ 0038 lineno = 1 0039 else: 0040 globals = caller.f_globals 0041 lineno = caller.f_lineno 0042 if '__name__' in globals: 0043 module = globals['__name__'] 0044 else: 0045 module = "<string>" 0046 filename = globals.get('__file__') 0047 if filename: 0048 fnl = filename.lower() 0049 if fnl.endswith(".pyc") or fnl.endswith(".pyo"): 0050 filename = filename[:-1] 0051 else: 0052 if module == "__main__": 0053 filename = sys.argv[0] 0054 if not filename: 0055 filename = module 0056 registry = globals.setdefault("__warningregistry__", {}) 0057 warn_explicit(message, category, filename, lineno, module, registry) 0058 0059 def warn_explicit(message, category, filename, lineno, 0060 module=None, registry=None): 0061 if module is None: 0062 module = filename 0063 if module[-3:].lower() == ".py": 0064 module = module[:-3] # XXX What about leading pathname? 0065 if registry is None: 0066 registry = {} 0067 if isinstance(message, Warning): 0068 text = str(message) 0069 category = message.__class__ 0070 else: 0071 text = message 0072 message = category(message) 0073 key = (text, category, lineno) 0074 # Quick test for common case 0075 if registry.get(key): 0076 return 0077 # Search the filters 0078 for item in filters: 0079 action, msg, cat, mod, ln = item 0080 if ((msg is None or msg.match(text)) and 0081 issubclass(category, cat) and 0082 (msg is None or mod.match(module)) and 0083 (ln == 0 or lineno == ln)): 0084 break 0085 else: 0086 action = defaultaction 0087 # Early exit actions 0088 if action == "ignore": 0089 registry[key] = 1 0090 return 0091 if action == "error": 0092 raise message 0093 # Other actions 0094 if action == "once": 0095 registry[key] = 1 0096 oncekey = (text, category) 0097 if onceregistry.get(oncekey): 0098 return 0099 onceregistry[oncekey] = 1 0100 elif action == "always": 0101 pass 0102 elif action == "module": 0103 registry[key] = 1 0104 altkey = (text, category, 0) 0105 if registry.get(altkey): 0106 return 0107 registry[altkey] = 1 0108 elif action == "default": 0109 registry[key] = 1 0110 else: 0111 # Unrecognized actions are errors 0112 raise RuntimeError( 0113 "Unrecognized action (%r) in warnings.filters:\n %s" % 0114 (action, item)) 0115 # Print message and context 0116 showwarning(message, category, filename, lineno) 0117 0118 def showwarning(message, category, filename, lineno, file=None): 0119 """Hook to write a warning to a file; replace if you like.""" 0120 if file is None: 0121 file = sys.stderr 0122 try: 0123 file.write(formatwarning(message, category, filename, lineno)) 0124 except IOError: 0125 pass # the file (probably stderr) is invalid - this warning gets lost. 0126 0127 def formatwarning(message, category, filename, lineno): 0128 """Function to format a warning the standard way.""" 0129 s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message) 0130 line = linecache.getline(filename, lineno).strip() 0131 if line: 0132 s = s + " " + line + "\n" 0133 return s 0134 0135 def filterwarnings(action, message="", category=Warning, module="", lineno=0, 0136 append=0): 0137 """Insert an entry into the list of warnings filters (at the front). 0138 0139 Use assertions to check that all arguments have the right type.""" 0140 import re 0141 assert action in ("error", "ignore", "always", "default", "module", 0142 "once"), "invalid action: %r" % (action,) 0143 assert isinstance(message, basestring), "message must be a string" 0144 assert isinstance(category, types.ClassType), "category must be a class" 0145 assert issubclass(category, Warning), "category must be a Warning subclass" 0146 assert isinstance(module, basestring), "module must be a string" 0147 assert isinstance(lineno, int) and lineno >= 0, \ 0148 "lineno must be an int >= 0" 0149 item = (action, re.compile(message, re.I), category, 0150 re.compile(module), lineno) 0151 if append: 0152 filters.append(item) 0153 else: 0154 filters.insert(0, item) 0155 0156 def simplefilter(action, category=Warning, lineno=0, append=0): 0157 """Insert a simple entry into the list of warnings filters (at the front). 0158 0159 A simple filter matches all modules and messages. 0160 """ 0161 assert action in ("error", "ignore", "always", "default", "module", 0162 "once"), "invalid action: %r" % (action,) 0163 assert isinstance(lineno, int) and lineno >= 0, \ 0164 "lineno must be an int >= 0" 0165 item = (action, None, category, None, lineno) 0166 if append: 0167 filters.append(item) 0168 else: 0169 filters.insert(0, item) 0170 0171 def resetwarnings(): 0172 """Clear the list of warning filters, so that no filters are active.""" 0173 filters[:] = [] 0174 0175 class _OptionError(Exception): 0176 """Exception used by option processing helpers.""" 0177 pass 0178 0179 # Helper to process -W options passed via sys.warnoptions 0180 def _processoptions(args): 0181 for arg in args: 0182 try: 0183 _setoption(arg) 0184 except _OptionError, msg: 0185 print >>sys.stderr, "Invalid -W option ignored:", msg 0186 0187 # Helper for _processoptions() 0188 def _setoption(arg): 0189 import re 0190 parts = arg.split(':') 0191 if len(parts) > 5: 0192 raise _OptionError("too many fields (max 5): %r" % (arg,)) 0193 while len(parts) < 5: 0194 parts.append('') 0195 action, message, category, module, lineno = [s.strip() 0196 for s in parts] 0197 action = _getaction(action) 0198 message = re.escape(message) 0199 category = _getcategory(category) 0200 module = re.escape(module) 0201 if module: 0202 module = module + '$' 0203 if lineno: 0204 try: 0205 lineno = int(lineno) 0206 if lineno < 0: 0207 raise ValueError 0208 except (ValueError, OverflowError): 0209 raise _OptionError("invalid lineno %r" % (lineno,)) 0210 else: 0211 lineno = 0 0212 filterwarnings(action, message, category, module, lineno) 0213 0214 # Helper for _setoption() 0215 def _getaction(action): 0216 if not action: 0217 return "default" 0218 if action == "all": return "always" # Alias 0219 for a in ['default', 'always', 'ignore', 'module', 'once', 'error']: 0220 if a.startswith(action): 0221 return a 0222 raise _OptionError("invalid action: %r" % (action,)) 0223 0224 # Helper for _setoption() 0225 def _getcategory(category): 0226 import re 0227 if not category: 0228 return Warning 0229 if re.match("^[a-zA-Z0-9_]+$", category): 0230 try: 0231 cat = eval(category) 0232 except NameError: 0233 raise _OptionError("unknown warning category: %r" % (category,)) 0234 else: 0235 i = category.rfind(".") 0236 module = category[:i] 0237 klass = category[i+1:] 0238 try: 0239 m = __import__(module, None, None, [klass]) 0240 except ImportError: 0241 raise _OptionError("invalid module name: %r" % (module,)) 0242 try: 0243 cat = getattr(m, klass) 0244 except AttributeError: 0245 raise _OptionError("unknown warning category: %r" % (category,)) 0246 if (not isinstance(cat, types.ClassType) or 0247 not issubclass(cat, Warning)): 0248 raise _OptionError("invalid warning category: %r" % (category,)) 0249 return cat 0250 0251 # Module initialization 0252 _processoptions(sys.warnoptions) 0253 # XXX OverflowWarning should go away for Python 2.5. 0254 simplefilter("ignore", category=OverflowWarning, append=1) 0255 simplefilter("ignore", category=PendingDeprecationWarning, append=1) 0256
Generated by PyXR 0.9.4