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