3
3
import sys as _sys
4
4
import warnings as _warnings
5
5
6
- from asyncio .events import BaseDefaultEventLoopPolicy as __BasePolicy
7
-
8
6
from . import includes as __includes # NOQA
9
7
from .loop import Loop as __BaseLoop # NOQA
10
8
from ._version import __version__ # NOQA
11
9
12
10
13
- __all__ = ('new_event_loop' , 'install' , 'EventLoopPolicy' )
11
+ __all__ : _typing .Tuple [str , ...] = ('new_event_loop' , 'run' )
12
+ _AbstractEventLoop = __asyncio .AbstractEventLoop
14
13
15
14
16
15
_T = _typing .TypeVar ("_T" )
17
16
18
17
19
- class Loop (__BaseLoop , __asyncio . AbstractEventLoop ): # type: ignore[misc]
18
+ class Loop (__BaseLoop , _AbstractEventLoop ): # type: ignore[misc]
20
19
pass
21
20
22
21
@@ -25,18 +24,6 @@ def new_event_loop() -> Loop:
25
24
return Loop ()
26
25
27
26
28
- def install () -> None :
29
- """A helper function to install uvloop policy."""
30
- if _sys .version_info [:2 ] >= (3 , 12 ):
31
- _warnings .warn (
32
- 'uvloop.install() is deprecated in favor of uvloop.run() '
33
- 'starting with Python 3.12.' ,
34
- DeprecationWarning ,
35
- stacklevel = 1 ,
36
- )
37
- __asyncio .set_event_loop_policy (EventLoopPolicy ())
38
-
39
-
40
27
if _typing .TYPE_CHECKING :
41
28
def run (
42
29
main : _typing .Coroutine [_typing .Any , _typing .Any , _T ],
@@ -114,7 +101,7 @@ async def wrapper():
114
101
)
115
102
116
103
117
- def _cancel_all_tasks (loop : __asyncio . AbstractEventLoop ) -> None :
104
+ def _cancel_all_tasks (loop : _AbstractEventLoop ) -> None :
118
105
# Copied from python/cpython
119
106
120
107
to_cancel = __asyncio .all_tasks (loop )
@@ -139,30 +126,108 @@ def _cancel_all_tasks(loop: __asyncio.AbstractEventLoop) -> None:
139
126
})
140
127
141
128
142
- class EventLoopPolicy (__BasePolicy ):
143
- """Event loop policy.
129
+ _deprecated_names = ('install' , 'EventLoopPolicy' )
130
+
131
+
132
+ if _sys .version_info [:2 ] < (3 , 16 ):
133
+ __all__ += _deprecated_names
134
+
135
+
136
+ def __getattr__ (name : str ) -> _typing .Any :
137
+ if name not in _deprecated_names :
138
+ raise AttributeError (f"module 'uvloop' has no attribute '{ name } '" )
139
+ elif _sys .version_info [:2 ] >= (3 , 16 ):
140
+ raise AttributeError (
141
+ f"module 'uvloop' has no attribute '{ name } ' "
142
+ f"(it was removed in Python 3.16, use uvloop.run() instead)"
143
+ )
144
+
145
+ import threading
146
+
147
+ def install () -> None :
148
+ """A helper function to install uvloop policy.
149
+
150
+ This function is deprecated and will be removed in Python 3.16.
151
+ Use `uvloop.run()` instead.
152
+ """
153
+ if _sys .version_info [:2 ] >= (3 , 12 ):
154
+ _warnings .warn (
155
+ 'uvloop.install() is deprecated in favor of uvloop.run() '
156
+ 'starting with Python 3.12.' ,
157
+ DeprecationWarning ,
158
+ stacklevel = 1 ,
159
+ )
160
+ __asyncio .set_event_loop_policy (EventLoopPolicy ())
161
+
162
+ class EventLoopPolicy (
163
+ # This is to avoid a mypy error about AbstractEventLoopPolicy
164
+ getattr (__asyncio , 'AbstractEventLoopPolicy' ) # type: ignore[misc]
165
+ ):
166
+ """Event loop policy for uvloop.
167
+
168
+ This class is deprecated and will be removed in Python 3.16.
169
+ Use `uvloop.run()` instead.
170
+
171
+ >>> import asyncio
172
+ >>> import uvloop
173
+ >>> asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
174
+ >>> asyncio.get_event_loop()
175
+ <uvloop.Loop running=False closed=False debug=False>
176
+ """
177
+
178
+ def _loop_factory (self ) -> Loop :
179
+ return new_event_loop ()
180
+
181
+ if _typing .TYPE_CHECKING :
182
+ # EventLoopPolicy doesn't implement these, but since they are
183
+ # marked as abstract in typeshed, we have to put them in so mypy
184
+ # thinks the base methods are overridden. This is the same approach
185
+ # taken for the Windows event loop policy classes in typeshed.
186
+ def get_child_watcher (self ) -> _typing .NoReturn :
187
+ ...
188
+
189
+ def set_child_watcher (
190
+ self , watcher : _typing .Any
191
+ ) -> _typing .NoReturn :
192
+ ...
193
+
194
+ class _Local (threading .local ):
195
+ _loop : _typing .Optional [_AbstractEventLoop ] = None
196
+
197
+ def __init__ (self ) -> None :
198
+ self ._local = self ._Local ()
199
+
200
+ def get_event_loop (self ) -> _AbstractEventLoop :
201
+ """Get the event loop for the current context.
202
+
203
+ Returns an instance of EventLoop or raises an exception.
204
+ """
205
+ if self ._local ._loop is None :
206
+ raise RuntimeError (
207
+ 'There is no current event loop in thread %r.'
208
+ % threading .current_thread ().name
209
+ )
144
210
145
- The preferred way to make your application use uvloop:
211
+ return self . _local . _loop
146
212
147
- >>> import asyncio
148
- >>> import uvloop
149
- >>> asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
150
- >>> asyncio.get_event_loop()
151
- <uvloop.Loop running=False closed=False debug=False>
152
- """
213
+ def set_event_loop (
214
+ self , loop : _typing .Optional [_AbstractEventLoop ]
215
+ ) -> None :
216
+ """Set the event loop."""
217
+ if loop is not None and not isinstance (loop , _AbstractEventLoop ):
218
+ raise TypeError (
219
+ f"loop must be an instance of AbstractEventLoop or None, "
220
+ f"not '{ type (loop ).__name__ } '"
221
+ )
222
+ self ._local ._loop = loop
153
223
154
- def _loop_factory (self ) -> Loop :
155
- return new_event_loop ()
224
+ def new_event_loop (self ) -> Loop :
225
+ """Create a new event loop.
156
226
157
- if _typing .TYPE_CHECKING :
158
- # EventLoopPolicy doesn't implement these, but since they are marked
159
- # as abstract in typeshed, we have to put them in so mypy thinks
160
- # the base methods are overridden. This is the same approach taken
161
- # for the Windows event loop policy classes in typeshed.
162
- def get_child_watcher (self ) -> _typing .NoReturn :
163
- ...
227
+ You must call set_event_loop() to make this the current event loop.
228
+ """
229
+ return self ._loop_factory ()
164
230
165
- def set_child_watcher (
166
- self , watcher : _typing .Any
167
- ) -> _typing .NoReturn :
168
- ...
231
+ globals ()['install' ] = install
232
+ globals ()['EventLoopPolicy' ] = EventLoopPolicy
233
+ return globals ()[name ]
0 commit comments