Skip to content

Commit 7e175f7

Browse files
committedJan 27, 2020
contexts: added 'breakable_section'
1 parent 55fb025 commit 7e175f7

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed
 

‎easypy/contexts.py

+34
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,37 @@ def some_other_context_manager():
107107

108108
def is_contextmanager(func):
109109
return getattr(func, "__code__", None) in _ctxm_code_samples
110+
111+
112+
@contextmanager
113+
def breakable_section():
114+
"""
115+
Useful for getting out of some deep nesting, as an alternative to a closure:
116+
117+
item = None
118+
with breakable_section() as Break:
119+
if alpha:
120+
item = alpha.value
121+
raise Break
122+
123+
if beta:
124+
for opt in beta.items:
125+
if opt.is_the_one:
126+
item = opt.value
127+
raise Break
128+
129+
Note that each 'Break' class this context-manager yield is unique,
130+
i.e it will only be caught by the context-manager that created it:
131+
132+
with breakable_section() as Break1:
133+
134+
with breakable_section() as Break2:
135+
raise Break1
136+
137+
assert False # will not reach here
138+
"""
139+
Break = type("Break", (Exception,), {})
140+
try:
141+
yield Break
142+
except Break:
143+
pass

‎tests/test_contexts.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import pytest
2-
from easypy.contexts import contextmanager
2+
from easypy.contexts import contextmanager, breakable_section
33

44

55
X = []
@@ -47,3 +47,21 @@ def foo():
4747
assert X == [1]
4848

4949
assert not X
50+
51+
52+
def test_breakable_section():
53+
54+
a = []
55+
with breakable_section() as Break1:
56+
with breakable_section() as Break2:
57+
with breakable_section() as Break3:
58+
raise Break2()
59+
a += [1] # this will be skipped
60+
a += [2] # this will be skipped
61+
a += [3] # landing here
62+
a += [4]
63+
64+
assert Break1 is not Break2
65+
assert Break2 is not Break3
66+
assert Break3 is not Break1
67+
assert a == [3, 4]

0 commit comments

Comments
 (0)
Please sign in to comment.