michael@0: from __future__ import with_statement michael@0: michael@0: import sys michael@0: michael@0: __all__ = ['nested', 'catch_warnings', 'examine_warnings'] michael@0: michael@0: michael@0: try: michael@0: from contextlib import nested michael@0: except ImportError: michael@0: from contextlib import contextmanager michael@0: @contextmanager michael@0: def nested(*managers): michael@0: exits = [] michael@0: vars = [] michael@0: exc = (None, None, None) michael@0: try: michael@0: for mgr in managers: michael@0: exit = mgr.__exit__ michael@0: enter = mgr.__enter__ michael@0: vars.append(enter()) michael@0: exits.append(exit) michael@0: yield vars michael@0: except: michael@0: exc = sys.exc_info() michael@0: finally: michael@0: while exits: michael@0: exit = exits.pop() michael@0: try: michael@0: if exit(*exc): michael@0: exc = (None, None, None) michael@0: except: michael@0: exc = sys.exc_info() michael@0: if exc != (None, None, None): michael@0: raise exc[1] michael@0: michael@0: # copied from Python 2.6 michael@0: try: michael@0: from warnings import catch_warnings michael@0: except ImportError: michael@0: class catch_warnings(object): michael@0: def __init__(self, record=False, module=None): michael@0: self._record = record michael@0: self._module = sys.modules['warnings'] michael@0: self._entered = False michael@0: michael@0: def __repr__(self): michael@0: args = [] michael@0: if self._record: michael@0: args.append("record=True") michael@0: name = type(self).__name__ michael@0: return "%s(%s)" % (name, ", ".join(args)) michael@0: michael@0: def __enter__(self): michael@0: if self._entered: michael@0: raise RuntimeError("Cannot enter %r twice" % self) michael@0: self._entered = True michael@0: self._filters = self._module.filters michael@0: self._module.filters = self._filters[:] michael@0: self._showwarning = self._module.showwarning michael@0: if self._record: michael@0: log = [] michael@0: def showwarning(*args, **kwargs): michael@0: log.append(WarningMessage(*args, **kwargs)) michael@0: self._module.showwarning = showwarning michael@0: return log michael@0: else: michael@0: return None michael@0: michael@0: def __exit__(self, *exc_info): michael@0: if not self._entered: michael@0: raise RuntimeError("Cannot exit %r without entering first" % self) michael@0: self._module.filters = self._filters michael@0: self._module.showwarning = self._showwarning michael@0: michael@0: class WarningMessage(object): michael@0: _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file", michael@0: "line") michael@0: def __init__(self, message, category, filename, lineno, file=None, michael@0: line=None): michael@0: local_values = locals() michael@0: for attr in self._WARNING_DETAILS: michael@0: setattr(self, attr, local_values[attr]) michael@0: self._category_name = None michael@0: if category.__name__: michael@0: self._category_name = category.__name__ michael@0: michael@0: michael@0: def examine_warnings(func): michael@0: def wrapper(): michael@0: with catch_warnings(record=True) as ws: michael@0: func(ws) michael@0: return wrapper