Skip to content

Commit b185539

Browse files
committed
-
1 parent 1a6a01c commit b185539

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

python_toolbox/context_managers/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,4 @@ def do_stuff():
133133
from .blank_context_manager import BlankContextManager
134134
from .reentrant_context_manager import ReentrantContextManager
135135
from .delegating_context_manager import DelegatingContextManager
136+
from .functions import nested
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright 2009-2012 Ram Rachum.
2+
# This program is distributed under the MIT license.
3+
4+
'''
5+
This module defines various functions.
6+
7+
See their documentation for more information.
8+
'''
9+
10+
from .context_manager_type import ContextManagerType
11+
12+
13+
@ContextManagerType
14+
def nested(*managers):
15+
# Code from `contextlib`
16+
exits = []
17+
vars = []
18+
exc = (None, None, None)
19+
try:
20+
for mgr in managers:
21+
exit = mgr.__exit__
22+
enter = mgr.__enter__
23+
vars.append(enter())
24+
exits.append(exit)
25+
yield vars
26+
except:
27+
exc = sys.exc_info()
28+
finally:
29+
while exits:
30+
exit = exits.pop()
31+
try:
32+
if exit(*exc):
33+
exc = (None, None, None)
34+
except:
35+
exc = sys.exc_info()
36+
if exc != (None, None, None):
37+
# Don't rely on sys.exc_info() still containing
38+
# the right information. Another exception may
39+
# have been raised and caught by an exit method
40+
raise exc[0], exc[1], exc[2]
41+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2009-2012 Ram Rachum.
2+
# This program is distributed under the MIT license.
3+
4+
'''Test the `python_toolbox.context_managers.nested` function.'''
5+
6+
from __future__ import with_statement
7+
8+
from python_toolbox import cute_testing
9+
10+
from python_toolbox.context_managers import ReentrantContextManager, nested
11+
12+
13+
14+
def test_nested():
15+
'''Test the basic workings of `nested`.'''
16+
17+
a = ReentrantContextManager()
18+
b = ReentrantContextManager()
19+
c = ReentrantContextManager()
20+
21+
with nested(a):
22+
assert (a.depth, b.depth, c.depth) == (1, 0, 0)
23+
with nested(a, b):
24+
assert (a.depth, b.depth, c.depth) == (2, 1, 0)
25+
with nested(a, b, c):
26+
assert (a.depth, b.depth, c.depth) == (3, 2, 1)
27+
28+
with nested(c):
29+
assert (a.depth, b.depth, c.depth) == (1, 0, 1)
30+
31+
assert (a.depth, b.depth, c.depth) == (0, 0, 0)
32+
33+

0 commit comments

Comments
 (0)