Skip to content

Commit fb993c1

Browse files
committed
yoo
1 parent 79456e5 commit fb993c1

File tree

2 files changed

+50
-26
lines changed

2 files changed

+50
-26
lines changed

source_py3/python_toolbox/context_management/functions.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
import sys
1111
import types
12+
import string
13+
import random
1214

1315
from python_toolbox import caching
1416

@@ -46,13 +48,31 @@ def nested(*managers):
4648
raise exc[1].with_traceback(exc[2])
4749

4850

49-
def _wrap_context_manager_or_context_generator(thing, wrapper_factory):
51+
def _wrap_context_manager_or_class(thing, wrapper_factory):
5052
if hasattr(type(thing), '__enter__'):
5153
# It's a context manager.
5254
return wrapper_factory(thing)
5355
else:
54-
assert isinstance(thing, types.FunctionType)
55-
# It's a context generator.
56+
assert issubclass(thing, ContextManager)
57+
# It's a context manager class.
58+
property_name = '__%s_context_manager_%s' % (
59+
thing.__name__,
60+
' '.join(random.choice(string.ascii_letters) for _ in range(20))
61+
)
62+
return type(
63+
thing.__name__,
64+
(thing,),
65+
{
66+
property_name: caching.CachedProperty(wrapper_factory),
67+
'__enter__':
68+
lambda self: getattr(self, property_name).__enter__(),
69+
'__exit__': lambda self, exc_type, exc_value, exc_traceback:
70+
getattr(self, property_name).
71+
__exit__(exc_type, exc_value, exc_traceback),
72+
73+
}
74+
)
75+
5676

5777

5878

@@ -76,7 +96,9 @@ def as_idempotent(context_manager):
7696
Note: The first value returned by `__enter__` will be returned by all the
7797
subsequent no-op `__enter__` calls.
7898
'''
79-
return _IdempotentContextManager(context_manager)
99+
return _wrap_context_manager_or_class(
100+
context_manager, _IdempotentContextManager
101+
)
80102

81103

82104
def as_reentrant(context_manager):
@@ -90,7 +112,9 @@ def as_reentrant(context_manager):
90112
Note: The first value returned by `__enter__` will be returned by all the
91113
subsequent no-op `__enter__` calls.
92114
'''
93-
return _ReentrantContextManager(context_manager)
115+
return _wrap_context_manager_or_class(
116+
context_manager, _ReentrantContextManager
117+
)
94118

95119

96120
class _IdempotentContextManager(ContextManager):

source_py3/test_python_toolbox/test_context_management/test_as_reentrant.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -150,30 +150,30 @@ def __exit__(self, exc_type, exc_value, exc_traceback):
150150
# happens *after* `.__wrapped__.__enter__` is called:
151151
assert depth_log.get(block=False) == 1
152152

153-
def test_decorator_manage_context():
154-
class Meow(ContextManager):
155-
n = 0
153+
# def test_decorator_manage_context():
154+
# class Meow(ContextManager):
155+
# n = 0
156156

157-
@as_reentrant
158-
def manage_context(self):
159-
self.n += 1
160-
try:
161-
yield
162-
finally:
163-
self.n -= 1
157+
# @as_reentrant
158+
# def manage_context(self):
159+
# self.n += 1
160+
# try:
161+
# yield
162+
# finally:
163+
# self.n -= 1
164164

165165

166-
meow = Meow()
167-
assert meow.n == 0
168-
with meow:
169-
assert meow.n == 1
170-
with meow:
171-
assert meow.n == 1
172-
with meow:
173-
assert meow.n == 1
174-
assert meow.n == 1
175-
assert meow.n == 1
176-
assert meow.n == 0
166+
# meow = Meow()
167+
# assert meow.n == 0
168+
# with meow:
169+
# assert meow.n == 1
170+
# with meow:
171+
# assert meow.n == 1
172+
# with meow:
173+
# assert meow.n == 1
174+
# assert meow.n == 1
175+
# assert meow.n == 1
176+
# assert meow.n == 0
177177

178178

179179
def test_decorator_class():

0 commit comments

Comments
 (0)