Skip to content

Commit 99bf248

Browse files
committed
use an outcome that clears itself
1 parent fd73280 commit 99bf248

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

src/trio/_threads.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import queue as stdlib_queue
77
import threading
88
from itertools import count
9-
from typing import TYPE_CHECKING, Generic, TypeVar
9+
from typing import TYPE_CHECKING, Generic, TypeVar, Protocol, Final, NoReturn
1010

1111
import attrs
1212
import outcome
@@ -36,6 +36,7 @@
3636
Ts = TypeVarTuple("Ts")
3737

3838
RetT = TypeVar("RetT")
39+
T_co = TypeVar("T_co", covariant=True)
3940

4041

4142
class _ParentTaskData(threading.local):
@@ -253,6 +254,32 @@ def run_in_system_nursery(self, token: TrioToken) -> None:
253254
token.run_sync_soon(self.run_sync)
254255

255256

257+
class _SupportsUnwrap(Protocol, Generic[T_co]):
258+
def unwrap(self) -> T_co: ...
259+
260+
261+
class _Value(_SupportsUnwrap[T_co]):
262+
def __init__(self, v: T_co) -> None:
263+
self._v: Final = v
264+
265+
def unwrap(self) -> T_co:
266+
try:
267+
return self._v
268+
finally:
269+
del self._v
270+
271+
272+
class _Error(_SupportsUnwrap[NoReturn]):
273+
def __init__(self, e: BaseException) -> None:
274+
self._e: Final = e
275+
276+
def unwrap(self) -> NoReturn:
277+
try:
278+
raise self._e
279+
finally:
280+
del self._e
281+
282+
256283
@enable_ki_protection
257284
async def to_thread_run_sync(
258285
sync_fn: Callable[[Unpack[Ts]], RetT],
@@ -372,11 +399,15 @@ def do_release_then_return_result() -> RetT:
372399
try:
373400
return result.unwrap()
374401
finally:
402+
del result
375403
limiter.release_on_behalf_of(placeholder)
376404

377405
result = outcome.capture(do_release_then_return_result)
406+
if isinstance(result, outcome.Error):
407+
result2: _SupportsUnwrap[RetT] = _Error(result.error)
408+
result2 = _Value(result.value)
378409
if task_register[0] is not None:
379-
trio.lowlevel.reschedule(task_register[0], outcome.Value(result))
410+
trio.lowlevel.reschedule(task_register[0], outcome.Value(result2))
380411

381412
current_trio_token = trio.lowlevel.current_trio_token()
382413

0 commit comments

Comments
 (0)