33from collections .abc import Callable
44from queue import SimpleQueue
55from threading import RLock
6- from typing import Any , Generic , TypeVar
6+ from typing import Any
77
88from .async_ import from_continuations , start_immediate
99from .async_builder import (
1414)
1515
1616
17- _Msg = TypeVar ("_Msg" )
18- _Reply = TypeVar ("_Reply" )
19-
20-
21- class AsyncReplyChannel (Generic [_Reply ]):
17+ class AsyncReplyChannel [Reply ]:
2218 def __init__ (self , fn : Callable [[Any ], None ]) -> None :
2319 self .fn = fn
2420
2521 def reply (self , r : Any ) -> None :
2622 self .fn (r )
2723
2824
29- class MailboxProcessor ( Generic [ _Msg ]) :
25+ class MailboxProcessor [ Msg ] :
3026 def __init__ (
3127 self ,
32- body : Callable [[MailboxProcessor [_Msg ]], Async [None ]],
28+ body : Callable [[MailboxProcessor [Msg ]], Async [None ]],
3329 cancellation_token : CancellationToken | None = None ,
3430 ):
35- self .messages : SimpleQueue [_Msg ] = SimpleQueue ()
31+ self .messages : SimpleQueue [Msg ] = SimpleQueue ()
3632 self .token = cancellation_token or CancellationToken ()
3733 self .lock = RLock ()
3834 self .body = body
3935
4036 # Holds the continuation i.e the `done` callback of Async.from_continuations returned by `receive`.
4137 self .continuation : Continuations [Any ] | None = None
4238
43- def post (self , msg : _Msg ) -> None :
39+ def post (self , msg : Msg ) -> None :
4440 """Post a message synchronously to the mailbox processor.
4541
4642 This method is not asynchronous since it's very fast to execute.
@@ -56,7 +52,7 @@ def post(self, msg: _Msg) -> None:
5652 self .messages .put (msg )
5753 self .__process_events ()
5854
59- def post_and_async_reply (self , build_message : Callable [[AsyncReplyChannel [_Reply ]], _Msg ]) -> Async [_Reply ]:
55+ def post_and_async_reply [ Reply ] (self , build_message : Callable [[AsyncReplyChannel [Reply ]], Msg ]) -> Async [Reply ]:
6056 """Post a message asynchronously to the mailbox processor and
6157 wait for the reply.
6258
@@ -70,7 +66,7 @@ def post_and_async_reply(self, build_message: Callable[[AsyncReplyChannel[_Reply
7066 The reply from mailbox processor.
7167 """
7268
73- result : _Reply | None = None
69+ result : Reply | None = None
7470 continuation : Continuations [Any ] | None = (
7571 None # This is the continuation for the `done` callback of the awaiting poster.
7672 )
@@ -79,12 +75,12 @@ def check_completion() -> None:
7975 if result is not None and continuation is not None :
8076 continuation [0 ](result )
8177
82- def reply_callback (res : _Reply ):
78+ def reply_callback (res : Reply ):
8379 nonlocal result
8480 result = res
8581 check_completion ()
8682
87- reply_channel : AsyncReplyChannel [_Reply ] = AsyncReplyChannel (reply_callback )
83+ reply_channel : AsyncReplyChannel [Reply ] = AsyncReplyChannel (reply_callback )
8884 self .messages .put (build_message (reply_channel ))
8985 self .__process_events ()
9086
@@ -95,7 +91,7 @@ def callback(conts: Continuations[Any]) -> None:
9591
9692 return from_continuations (callback )
9793
98- def receive (self ) -> Async [_Msg ]:
94+ def receive (self ) -> Async [Msg ]:
9995 """Receive message from mailbox.
10096
10197 Returns:
@@ -139,31 +135,37 @@ def __process_events(self) -> None:
139135 @classmethod
140136 def start (
141137 cls ,
142- body : Callable [[MailboxProcessor [_Msg ]], Async [None ]],
138+ body : Callable [[MailboxProcessor [Msg ]], Async [None ]],
143139 cancellation_token : CancellationToken | None = None ,
144- ) -> MailboxProcessor [_Msg ]:
145- mbox : MailboxProcessor [_Msg ] = MailboxProcessor (body , cancellation_token )
140+ ) -> MailboxProcessor [Msg ]:
141+ mbox : MailboxProcessor [Msg ] = MailboxProcessor (body , cancellation_token )
146142 start_immediate (body (mbox ))
147143 return mbox
148144
149145
150- def receive (mbox : MailboxProcessor [_Msg ]) -> Async [_Msg ]:
146+ def receive [ Msg ] (mbox : MailboxProcessor [Msg ]) -> Async [Msg ]:
151147 return mbox .receive ()
152148
153149
154- def post (mbox : MailboxProcessor [_Msg ], msg : _Msg ):
150+ def post [ Msg ] (mbox : MailboxProcessor [Msg ], msg : Msg ):
155151 return mbox .post (msg )
156152
157153
154+ def post_and_async_reply [Msg , Reply ](
155+ mbox : MailboxProcessor [Msg ], build_message : Callable [[AsyncReplyChannel [Reply ]], Msg ]
156+ ) -> Async [Reply ]:
157+ return mbox .post_and_async_reply (build_message )
158+
159+
158160def start_instance (mbox : MailboxProcessor [Any ]) -> None :
159161 body = mbox .body (mbox )
160162 return start_immediate (body )
161163
162164
163- def start (
164- body : Callable [[MailboxProcessor [_Msg ]], Async [None ]],
165+ def start [ Msg ] (
166+ body : Callable [[MailboxProcessor [Msg ]], Async [None ]],
165167 cancellationToken : CancellationToken | None = None ,
166- ) -> MailboxProcessor [_Msg ]:
168+ ) -> MailboxProcessor [Msg ]:
167169 mbox = MailboxProcessor (body , cancellationToken )
168170 start_instance (mbox )
169171 return mbox
@@ -173,6 +175,7 @@ def start(
173175 "AsyncReplyChannel" ,
174176 "MailboxProcessor" ,
175177 "post" ,
178+ "post_and_async_reply" ,
176179 "receive" ,
177180 "start" ,
178181 "start_instance" ,
0 commit comments