33import sys as _sys
44import warnings as _warnings
55
6- try :
7- from asyncio .events import BaseDefaultEventLoopPolicy as __BasePolicy
8- except ImportError :
9- # https://github.com/python/cpython/issues/131148
10- from asyncio .events import _BaseDefaultEventLoopPolicy as __BasePolicy
11-
126from . import includes as __includes # NOQA
137from .loop import Loop as __BaseLoop # NOQA
148from ._version import __version__ # NOQA
159
1610
17- __all__ = ('new_event_loop' , 'install' , 'EventLoopPolicy' )
11+ __all__ : tuple [ str , ...] = ('new_event_loop' ,)
1812
1913
2014_T = _typing .TypeVar ("_T" )
@@ -29,18 +23,6 @@ def new_event_loop() -> Loop:
2923 return Loop ()
3024
3125
32- def install () -> None :
33- """A helper function to install uvloop policy."""
34- if _sys .version_info [:2 ] >= (3 , 12 ):
35- _warnings .warn (
36- 'uvloop.install() is deprecated in favor of uvloop.run() '
37- 'starting with Python 3.12.' ,
38- DeprecationWarning ,
39- stacklevel = 1 ,
40- )
41- __asyncio .set_event_loop_policy (EventLoopPolicy ())
42-
43-
4426if _typing .TYPE_CHECKING :
4527 def run (
4628 main : _typing .Coroutine [_typing .Any , _typing .Any , _T ],
@@ -143,30 +125,91 @@ def _cancel_all_tasks(loop: __asyncio.AbstractEventLoop) -> None:
143125 })
144126
145127
146- class EventLoopPolicy ( __BasePolicy ):
147- """Event loop policy.
128+ if _sys . version_info [: 2 ] < ( 3 , 16 ):
129+ import threading as _threading
148130
149- The preferred way to make your application use uvloop:
131+ __all__ += ( 'install' , 'EventLoopPolicy' )
150132
151- >>> import asyncio
152- >>> import uvloop
153- >>> asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
154- >>> asyncio.get_event_loop()
155- <uvloop.Loop running=False closed=False debug=False>
156- """
133+ def install () -> None :
134+ """A helper function to install uvloop policy.
157135
158- def _loop_factory (self ) -> Loop :
159- return new_event_loop ()
136+ This function is deprecated and will be removed in Python 3.16.
137+ Use `uvloop.run()` instead.
138+ """
139+ if _sys .version_info [:2 ] >= (3 , 12 ):
140+ _warnings .warn (
141+ 'uvloop.install() is deprecated in favor of uvloop.run() '
142+ 'starting with Python 3.12.' ,
143+ DeprecationWarning ,
144+ stacklevel = 1 ,
145+ )
146+ __asyncio .set_event_loop_policy (EventLoopPolicy ())
147+
148+ class EventLoopPolicy (
149+ __asyncio .AbstractEventLoopPolicy # type: ignore[name-defined,misc]
150+ ):
151+ """Event loop policy for uvloop.
152+
153+ This class is deprecated and will be removed in Python 3.16.
154+ Use `uvloop.run()` instead.
155+
156+ >>> import asyncio
157+ >>> import uvloop
158+ >>> asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
159+ >>> asyncio.get_event_loop()
160+ <uvloop.Loop running=False closed=False debug=False>
161+ """
162+
163+ def _loop_factory (self ) -> Loop :
164+ return new_event_loop ()
165+
166+ if _typing .TYPE_CHECKING :
167+ # EventLoopPolicy doesn't implement these, but since they are
168+ # marked as abstract in typeshed, we have to put them in so mypy
169+ # thinks the base methods are overridden. This is the same approach
170+ # taken for the Windows event loop policy classes in typeshed.
171+ def get_child_watcher (self ) -> _typing .NoReturn :
172+ ...
173+
174+ def set_child_watcher (
175+ self , watcher : _typing .Any
176+ ) -> _typing .NoReturn :
177+ ...
178+
179+ class _Local (_threading .local ):
180+ _loop : _typing .Optional [Loop ] = None
181+
182+ def __init__ (self ) -> None :
183+ self ._local = self ._Local ()
184+
185+ def get_event_loop (self ) -> Loop :
186+ """Get the event loop for the current context.
187+
188+ Returns an instance of EventLoop or raises an exception.
189+ """
190+ if self ._local ._loop is None :
191+ raise RuntimeError (
192+ 'There is no current event loop in thread %r.'
193+ % _threading .current_thread ().name
194+ )
195+
196+ return self ._local ._loop
197+
198+ def set_event_loop (self , loop : Loop ) -> None :
199+ """Set the event loop."""
200+ if loop is not None and not isinstance (
201+ loop , __asyncio .AbstractEventLoop
202+ ):
203+ raise TypeError (
204+ f"loop must be an instance of AbstractEventLoop or None, "
205+ f"not '{ type (loop ).__name__ } '"
206+ )
207+ self ._local ._loop = loop
160208
161- if _typing .TYPE_CHECKING :
162- # EventLoopPolicy doesn't implement these, but since they are marked
163- # as abstract in typeshed, we have to put them in so mypy thinks
164- # the base methods are overridden. This is the same approach taken
165- # for the Windows event loop policy classes in typeshed.
166- def get_child_watcher (self ) -> _typing .NoReturn :
167- ...
209+ def new_event_loop (self ) -> Loop :
210+ """Create a new event loop.
168211
169- def set_child_watcher (
170- self , watcher : _typing . Any
171- ) -> _typing . NoReturn :
172- ...
212+ You must call set_event_loop() to make this the current event
213+ loop.
214+ """
215+ return self . _loop_factory ()
0 commit comments