44import time
55from typing import Any , Callable , Coroutine , Optional , Protocol , TypeVar , Union , cast
66
7- from . import _serialization
8-
97T = TypeVar ("T" )
108R = TypeVar ("R" )
119
1210
11+ class NoResult :
12+ _instance : Optional ["NoResult" ] = None
13+ __slots__ = ()
14+
15+ def __new__ (cls , * args : Any , ** kwargs : Any ) -> "NoResult" :
16+ if not cls ._instance :
17+ cls ._instance = super (NoResult , cls ).__new__ (cls , * args , ** kwargs )
18+ return cls ._instance
19+
20+
1321# define Outcome protocol w/ common composition methods
1422class Outcome (Protocol [T ]):
1523
@@ -30,7 +38,9 @@ def retry(
3038 exceeded_retries : Callable [[int ], BaseException ],
3139 ) -> "Outcome[T]" : ...
3240
33- def intercept (self , interceptor : Callable [[], Optional [str ]]) -> "Outcome[T]" : ...
41+ def intercept (
42+ self , interceptor : Callable [[], Union [NoResult , T ]]
43+ ) -> "Outcome[T]" : ...
3444
3545 def __call__ (self ) -> Union [T , Coroutine [Any , Any , T ]]: ...
3646
@@ -61,14 +71,14 @@ def wrap(
6171
6272 @staticmethod
6373 def _intercept (
64- func : Callable [[], T ], interceptor : Callable [[], Optional [ str ]]
74+ func : Callable [[], T ], interceptor : Callable [[], Union [ NoResult , T ]]
6575 ) -> T :
6676 intercepted = interceptor ()
67- return (
68- cast (T , _serialization .deserialize (intercepted )) if intercepted else func ()
69- )
77+ return intercepted if not isinstance (intercepted , NoResult ) else func ()
7078
71- def intercept (self , interceptor : Callable [[], Optional [str ]]) -> "Immediate[T]" :
79+ def intercept (
80+ self , interceptor : Callable [[], Union [NoResult , T ]]
81+ ) -> "Immediate[T]" :
7282 return Immediate [T ](lambda : Immediate ._intercept (self ._func , interceptor ))
7383
7484 @staticmethod
@@ -157,16 +167,12 @@ def also(self, cm: contextlib.AbstractContextManager[Any, bool]) -> "Pending[T]"
157167 @staticmethod
158168 async def _intercept (
159169 func : Callable [[], Coroutine [Any , Any , T ]],
160- interceptor : Callable [[], Optional [ str ]],
170+ interceptor : Callable [[], Union [ NoResult , T ]],
161171 ) -> T :
162172 intercepted = await asyncio .to_thread (interceptor )
163- return (
164- cast (T , _serialization .deserialize (intercepted ))
165- if intercepted
166- else await func ()
167- )
173+ return intercepted if not isinstance (intercepted , NoResult ) else await func ()
168174
169- def intercept (self , interceptor : Callable [[], Optional [ str ]]) -> "Pending[T]" :
175+ def intercept (self , interceptor : Callable [[], Union [ NoResult , T ]]) -> "Pending[T]" :
170176 return Pending [T ](lambda : Pending ._intercept (self ._func , interceptor ))
171177
172178 @staticmethod
0 commit comments