Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 from __future__ import with_statement
3 import sys
5 __all__ = ['nested', 'catch_warnings', 'examine_warnings']
8 try:
9 from contextlib import nested
10 except ImportError:
11 from contextlib import contextmanager
12 @contextmanager
13 def nested(*managers):
14 exits = []
15 vars = []
16 exc = (None, None, None)
17 try:
18 for mgr in managers:
19 exit = mgr.__exit__
20 enter = mgr.__enter__
21 vars.append(enter())
22 exits.append(exit)
23 yield vars
24 except:
25 exc = sys.exc_info()
26 finally:
27 while exits:
28 exit = exits.pop()
29 try:
30 if exit(*exc):
31 exc = (None, None, None)
32 except:
33 exc = sys.exc_info()
34 if exc != (None, None, None):
35 raise exc[1]
37 # copied from Python 2.6
38 try:
39 from warnings import catch_warnings
40 except ImportError:
41 class catch_warnings(object):
42 def __init__(self, record=False, module=None):
43 self._record = record
44 self._module = sys.modules['warnings']
45 self._entered = False
47 def __repr__(self):
48 args = []
49 if self._record:
50 args.append("record=True")
51 name = type(self).__name__
52 return "%s(%s)" % (name, ", ".join(args))
54 def __enter__(self):
55 if self._entered:
56 raise RuntimeError("Cannot enter %r twice" % self)
57 self._entered = True
58 self._filters = self._module.filters
59 self._module.filters = self._filters[:]
60 self._showwarning = self._module.showwarning
61 if self._record:
62 log = []
63 def showwarning(*args, **kwargs):
64 log.append(WarningMessage(*args, **kwargs))
65 self._module.showwarning = showwarning
66 return log
67 else:
68 return None
70 def __exit__(self, *exc_info):
71 if not self._entered:
72 raise RuntimeError("Cannot exit %r without entering first" % self)
73 self._module.filters = self._filters
74 self._module.showwarning = self._showwarning
76 class WarningMessage(object):
77 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
78 "line")
79 def __init__(self, message, category, filename, lineno, file=None,
80 line=None):
81 local_values = locals()
82 for attr in self._WARNING_DETAILS:
83 setattr(self, attr, local_values[attr])
84 self._category_name = None
85 if category.__name__:
86 self._category_name = category.__name__
89 def examine_warnings(func):
90 def wrapper():
91 with catch_warnings(record=True) as ws:
92 func(ws)
93 return wrapper