Skip to content

Commit b4bb54c

Browse files
committed
demonstrate benefits of unwrap_and_destroy
1 parent 5fd1f61 commit b4bb54c

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

tests/test_async.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55

66
import outcome
77
from outcome import AlreadyUsedError, Error, Value
8+
import weakref
9+
import sys
10+
import contextlib
11+
import types
12+
import outcome
13+
import platform
14+
import gc
815

916
pytestmark = pytest.mark.asyncio
1017

@@ -58,3 +65,60 @@ async def raise_ValueError(x):
5865
frames = traceback.extract_tb(exc_info.value.__traceback__)
5966
functions = [function for _, _, function, _ in frames]
6067
assert functions[-2:] == ['unwrap', 'raise_ValueError']
68+
69+
70+
@types.coroutine
71+
def async_yield(v):
72+
return (yield v)
73+
74+
75+
async def test_unwrap_leaves_a_refcycle():
76+
class MyException(Exception):
77+
pass
78+
79+
async def network_operation():
80+
return (await async_yield("network operation")).unwrap()
81+
82+
async def coro_fn():
83+
try:
84+
await network_operation()
85+
except MyException as e:
86+
wr_e = weakref.ref(e)
87+
del e
88+
89+
if platform.python_implementation() == "PyPy":
90+
gc.collect()
91+
assert isinstance(wr_e(), MyException)
92+
93+
with contextlib.closing(coro_fn()) as coro:
94+
assert coro.send(None) == "network operation"
95+
with pytest.raises(StopIteration):
96+
coro.send(outcome.Error(MyException()))
97+
98+
99+
async def test_unwrap_and_destroy_does_not_leave_a_refcycle():
100+
class MyException(Exception):
101+
pass
102+
103+
async def network_operation():
104+
return (await async_yield("network operation")).unwrap_and_destroy()
105+
106+
async def coro_fn():
107+
try:
108+
await network_operation()
109+
except MyException as e:
110+
wr_e = weakref.ref(e)
111+
del e
112+
113+
if platform.python_implementation() == "PyPy":
114+
gc.collect()
115+
assert wr_e() is None
116+
117+
with contextlib.closing(coro_fn()) as coro:
118+
assert coro.send(None) == "network operation"
119+
with pytest.raises(StopIteration):
120+
coro.send(outcome.Error(MyException()))
121+
122+
123+
if __name__ == "__main__":
124+
sys.exit(main())

0 commit comments

Comments
 (0)