13
13
__all__ = ('new_event_loop' , 'install' , 'EventLoopPolicy' )
14
14
15
15
16
+ _T = _typing .TypeVar ("_T" )
17
+
18
+
16
19
class Loop (__BaseLoop , __asyncio .AbstractEventLoop ): # type: ignore[misc]
17
20
pass
18
21
@@ -34,69 +37,78 @@ def install() -> None:
34
37
__asyncio .set_event_loop_policy (EventLoopPolicy ())
35
38
36
39
37
- def run (main , * , loop_factory = new_event_loop , debug = None , ** run_kwargs ):
38
- """The preferred way of running a coroutine with uvloop."""
39
-
40
- async def wrapper ():
41
- # If `loop_factory` is provided we want it to return
42
- # either uvloop.Loop or a subtype of it, assuming the user
43
- # is using `uvloop.run()` intentionally.
44
- loop = __asyncio ._get_running_loop ()
45
- if not isinstance (loop , Loop ):
46
- raise TypeError ('uvloop.run() uses a non-uvloop event loop' )
47
- return await main
48
-
49
- vi = _sys .version_info [:2 ]
50
-
51
- if vi <= (3 , 10 ):
52
- # Copied from python/cpython
53
-
54
- if __asyncio ._get_running_loop () is not None :
55
- raise RuntimeError (
56
- "asyncio.run() cannot be called from a running event loop" )
57
-
58
- if not __asyncio .iscoroutine (main ):
59
- raise ValueError ("a coroutine was expected, got {!r}" .format (main ))
60
-
61
- loop = loop_factory ()
62
- try :
63
- __asyncio .set_event_loop (loop )
64
- if debug is not None :
65
- loop .set_debug (debug )
66
- return loop .run_until_complete (wrapper ())
67
- finally :
40
+ if _typing .TYPE_CHECKING :
41
+ def run (
42
+ main : _typing .Coroutine [_typing .Any , _typing .Any , _T ],
43
+ * ,
44
+ loop_factory : _typing .Optional [_typing .Callable [[], Loop ]] = new_event_loop ,
45
+ debug : _typing .Optional [bool ]= None ,
46
+ ) -> _T :
47
+ """The preferred way of running a coroutine with uvloop."""
48
+ else :
49
+ def run (main , * , loop_factory = new_event_loop , debug = None , ** run_kwargs ):
50
+ """The preferred way of running a coroutine with uvloop."""
51
+
52
+ async def wrapper ():
53
+ # If `loop_factory` is provided we want it to return
54
+ # either uvloop.Loop or a subtype of it, assuming the user
55
+ # is using `uvloop.run()` intentionally.
56
+ loop = __asyncio ._get_running_loop ()
57
+ if not isinstance (loop , Loop ):
58
+ raise TypeError ('uvloop.run() uses a non-uvloop event loop' )
59
+ return await main
60
+
61
+ vi = _sys .version_info [:2 ]
62
+
63
+ if vi <= (3 , 10 ):
64
+ # Copied from python/cpython
65
+
66
+ if __asyncio ._get_running_loop () is not None :
67
+ raise RuntimeError (
68
+ "asyncio.run() cannot be called from a running event loop" )
69
+
70
+ if not __asyncio .iscoroutine (main ):
71
+ raise ValueError ("a coroutine was expected, got {!r}" .format (main ))
72
+
73
+ loop = loop_factory ()
68
74
try :
69
- _cancel_all_tasks (loop )
70
- loop . run_until_complete ( loop . shutdown_asyncgens ())
71
- if hasattr ( loop , 'shutdown_default_executor' ):
72
- loop .run_until_complete (loop . shutdown_default_executor ())
75
+ __asyncio . set_event_loop (loop )
76
+ if debug is not None :
77
+ loop . set_debug ( debug )
78
+ return loop .run_until_complete (wrapper ())
73
79
finally :
74
- __asyncio .set_event_loop (None )
75
- loop .close ()
76
-
77
- elif vi == (3 , 11 ):
78
- if __asyncio ._get_running_loop () is not None :
79
- raise RuntimeError (
80
- "asyncio.run() cannot be called from a running event loop" )
81
-
82
- with __asyncio .Runner (
83
- loop_factory = loop_factory ,
84
- debug = debug ,
85
- ** run_kwargs
86
- ) as runner :
87
- return runner .run (wrapper ())
88
-
89
- else :
90
- assert vi >= (3 , 12 )
91
- return __asyncio .run (
92
- wrapper (),
93
- loop_factory = loop_factory ,
94
- debug = debug ,
95
- ** run_kwargs
96
- )
97
-
98
-
99
- def _cancel_all_tasks (loop ):
80
+ try :
81
+ _cancel_all_tasks (loop )
82
+ loop .run_until_complete (loop .shutdown_asyncgens ())
83
+ if hasattr (loop , 'shutdown_default_executor' ):
84
+ loop .run_until_complete (loop .shutdown_default_executor ())
85
+ finally :
86
+ __asyncio .set_event_loop (None )
87
+ loop .close ()
88
+
89
+ elif vi == (3 , 11 ):
90
+ if __asyncio ._get_running_loop () is not None :
91
+ raise RuntimeError (
92
+ "asyncio.run() cannot be called from a running event loop" )
93
+
94
+ with __asyncio .Runner (
95
+ loop_factory = loop_factory ,
96
+ debug = debug ,
97
+ ** run_kwargs
98
+ ) as runner :
99
+ return runner .run (wrapper ())
100
+
101
+ else :
102
+ assert vi >= (3 , 12 )
103
+ return __asyncio .run (
104
+ wrapper (),
105
+ loop_factory = loop_factory ,
106
+ debug = debug ,
107
+ ** run_kwargs
108
+ )
109
+
110
+
111
+ def _cancel_all_tasks (loop : __asyncio .AbstractEventLoop ) -> None :
100
112
# Copied from python/cpython
101
113
102
114
to_cancel = __asyncio .all_tasks (loop )
0 commit comments