| OLD | NEW |
|---|---|
| 1 """Python part of the warnings subsystem.""" | 1 """Python part of the warnings subsystem.""" |
| 2 | 2 |
| 3 # Note: function level imports should *not* be used | 3 # Note: function level imports should *not* be used |
| 4 # in this module as it may cause import lock deadlock. | 4 # in this module as it may cause import lock deadlock. |
| 5 # See bug 683658. | 5 # See bug 683658. |
| 6 import linecache | 6 import linecache |
| 7 import sys | 7 import sys |
| 8 import types | 8 import types |
| 9 | 9 |
| 10 __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings", | 10 __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings", |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 registry[key] = 1 | 259 registry[key] = 1 |
| 260 else: | 260 else: |
| 261 # Unrecognized actions are errors | 261 # Unrecognized actions are errors |
| 262 raise RuntimeError( | 262 raise RuntimeError( |
| 263 "Unrecognized action (%r) in warnings.filters:\n %s" % | 263 "Unrecognized action (%r) in warnings.filters:\n %s" % |
| 264 (action, item)) | 264 (action, item)) |
| 265 # Warn if showwarning() does not support the 'line' argument. | 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 | 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. | 267 # build thanks to 'warnings' being imported by setup.py. |
| 268 fxn_code = None | 268 fxn_code = None |
| 269 if hasattr(showwarning, 'func_code'): | 269 if hasattr(showwarning, 'func_code'): |
|
Benjamin
2008/08/23 01:46:36
This stuff is pretty nasty. Can you use inspect?
| |
| 270 fxn_code = showwarning.func_code | 270 fxn_code = showwarning.func_code |
| 271 elif hasattr(showwarning, '__func__'): | 271 elif hasattr(showwarning, '__func__'): |
| 272 fxn_code = showwarning.__func__.func_code | 272 fxn_code = showwarning.__func__.func_code |
| 273 if fxn_code: | 273 if fxn_code: |
| 274 args = fxn_code.co_varnames[:fxn_code.co_argcount] | 274 args = fxn_code.co_varnames[:fxn_code.co_argcount] |
| 275 if 'line' not in args: | 275 CO_VARARGS = 0x4 |
| 276 if 'line' not in args and not fxn_code.co_flags & CO_VARARGS: | |
| 276 showwarning_msg = ("functions overriding warnings.showwarning() " | 277 showwarning_msg = ("functions overriding warnings.showwarning() " |
| 277 "must support the 'line' argument") | 278 "must support the 'line' argument") |
| 278 if message == showwarning_msg: | 279 if message == showwarning_msg: |
| 279 _show_warning(message, category, filename, lineno) | 280 _show_warning(message, category, filename, lineno) |
| 280 else: | 281 else: |
| 281 warn(showwarning_msg, DeprecationWarning) | 282 warn(showwarning_msg, DeprecationWarning) |
| 282 # Print message and context | 283 # Print message and context |
| 283 showwarning(message, category, filename, lineno) | 284 showwarning(message, category, filename, lineno) |
| 285 | |
| 286 | |
| 287 class WarningMessage(object): | |
|
Benjamin
2008/08/23 01:46:36
What happened to the idea of making this a namedtu
brett.cannon
2008/08/23 02:19:54
On 2008/08/23 01:46:36, Benjamin wrote:
> What hap
| |
| 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 WarningsRecorder(list): | |
| 308 | |
| 309 """Record the result of various showwarning() calls.""" | |
| 310 | |
| 311 # Explicitly stated arguments so as to not trigger DeprecationWarning | |
| 312 # about adding 'line'. | |
| 313 def showwarning(self, *args, **kwargs): | |
| 314 self.append(WarningMessage(*args, **kwargs)) | |
| 315 | |
| 316 def __getattr__(self, attr): | |
| 317 return getattr(self[-1], attr) | |
| 318 | |
| 319 def reset(self): | |
| 320 while True: | |
|
Benjamin
2008/08/23 01:46:36
Can't this be "del self[:]"?
brett.cannon
2008/08/23 02:19:54
On 2008/08/23 01:46:36, Benjamin wrote:
> Can't th
| |
| 321 try: | |
| 322 self.pop() | |
| 323 except IndexError: | |
| 324 break | |
| 325 | |
| 326 | |
| 327 class catch_warnings(object): | |
|
Benjamin
2008/08/23 01:46:36
Shouldn't this be called "catchwarnings"?
Benjamin
2008/08/23 01:46:36
Can't this be a simple generator contextmanager?
brett.cannon
2008/08/23 02:19:54
On 2008/08/23 01:46:36, Benjamin wrote:
> Shouldn'
brett.cannon
2008/08/23 02:19:54
On 2008/08/23 01:46:36, Benjamin wrote:
> Can't th
| |
| 328 | |
| 329 """Guard the warnings filter from being permanently changed and optionally | |
| 330 record the details of any warnings that are issued. | |
| 331 | |
| 332 Context manager returns an instance of warnings.WarningRecorder which is a | |
| 333 list of WarningMessage instances. Attributes on WarningRecorder are | |
| 334 redirected to the last created WarningMessage instance. | |
| 335 | |
| 336 """ | |
| 337 | |
| 338 def __init__(self, record=False, module=None): | |
| 339 """Specify whether to record warnings and if an alternative module | |
| 340 should be used other than sys.modules['warnings']. | |
| 341 | |
| 342 For compatibility with Python 3.0, please consider all arguments to be | |
| 343 keyword-only. | |
| 344 | |
| 345 """ | |
| 346 self._recorder = WarningsRecorder() if record else None | |
| 347 self._module = sys.modules['warnings'] if module is None else module | |
| 348 | |
| 349 def __enter__(self): | |
| 350 self._filters = self._module.filters | |
| 351 self._module.filters = self._filters[:] | |
| 352 self._showwarning = self._module.showwarning | |
| 353 if self._recorder is not None: | |
| 354 self._recorder.reset() # In case the instance is being reused. | |
| 355 self._module.showwarning = self._recorder.showwarning | |
| 356 return self._recorder | |
| 357 | |
| 358 def __exit__(self, *exc_info): | |
| 359 self._module.filters = self._filters | |
| 360 self._module.showwarning = self._showwarning | |
| 284 | 361 |
| 285 | 362 |
| 286 # filters contains a sequence of filter 5-tuples | 363 # filters contains a sequence of filter 5-tuples |
| 287 # The components of the 5-tuple are: | 364 # The components of the 5-tuple are: |
| 288 # - an action: error, ignore, always, default, module, or once | 365 # - an action: error, ignore, always, default, module, or once |
| 289 # - a compiled regex that must match the warning message | 366 # - a compiled regex that must match the warning message |
| 290 # - a class representing the warning category | 367 # - a class representing the warning category |
| 291 # - a compiled regex that must match the module that is being warned | 368 # - a compiled regex that must match the module that is being warned |
| 292 # - a line number for the line being warning, or 0 to mean any line | 369 # - a line number for the line being warning, or 0 to mean any line |
| 293 # If either if the compiled regexs are None, match anything. | 370 # If either if the compiled regexs are None, match anything. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 311 simplefilter("ignore", category=ImportWarning, append=1) | 388 simplefilter("ignore", category=ImportWarning, append=1) |
| 312 bytes_warning = sys.flags.bytes_warning | 389 bytes_warning = sys.flags.bytes_warning |
| 313 if bytes_warning > 1: | 390 if bytes_warning > 1: |
| 314 bytes_action = "error" | 391 bytes_action = "error" |
| 315 elif bytes_warning: | 392 elif bytes_warning: |
| 316 bytes_action = "default" | 393 bytes_action = "default" |
| 317 else: | 394 else: |
| 318 bytes_action = "ignore" | 395 bytes_action = "ignore" |
| 319 simplefilter(bytes_action, category=BytesWarning, append=1) | 396 simplefilter(bytes_action, category=BytesWarning, append=1) |
| 320 del _warnings_defaults | 397 del _warnings_defaults |
| OLD | NEW |