@@ -147,6 +147,7 @@ pub mod doc_test {
147
147
148
148
static ASYNCIO : OnceCell < PyObject > = OnceCell :: new ( ) ;
149
149
static ENSURE_FUTURE : OnceCell < PyObject > = OnceCell :: new ( ) ;
150
+ static GET_RUNNING_LOOP : OnceCell < PyObject > = OnceCell :: new ( ) ;
150
151
151
152
const EXPECT_INIT : & str = "PyO3 Asyncio has not been initialized" ;
152
153
static CACHED_EVENT_LOOP : OnceCell < PyObject > = OnceCell :: new ( ) ;
@@ -261,10 +262,28 @@ fn asyncio_get_event_loop(py: Python) -> PyResult<&PyAny> {
261
262
}
262
263
263
264
/// Get a reference to the Python Event Loop from Rust
265
+ ///
266
+ /// Equivalent to `asyncio.get_running_loop()` in Python 3.7+
267
+ /// > For Python 3.6, this function falls back to `asyncio.get_event_loop()` which has slightly
268
+ /// different behaviour. See the [`asyncio.get_event_loop`](https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.get_event_loop)
269
+ /// docs to better understand the differences.
264
270
pub fn get_running_loop ( py : Python ) -> PyResult < & PyAny > {
265
271
// Ideally should call get_running_loop, but calls get_event_loop for compatibility between
266
272
// versions.
267
- asyncio ( py) ?. call_method0 ( "get_event_loop" )
273
+ GET_RUNNING_LOOP
274
+ . get_or_try_init ( || -> PyResult < PyObject > {
275
+ let asyncio = asyncio ( py) ?;
276
+
277
+ if asyncio. hasattr ( "get_running_loop" ) ? {
278
+ // correct behaviour with Python 3.7+
279
+ Ok ( asyncio. getattr ( "get_running_loop" ) ?. into ( ) )
280
+ } else {
281
+ // Python 3.6 compatibility mode
282
+ Ok ( asyncio. getattr ( "get_event_loop" ) ?. into ( ) )
283
+ }
284
+ } ) ?
285
+ . as_ref ( py)
286
+ . call0 ( )
268
287
}
269
288
270
289
/// Get a reference to the Python event loop cached by `try_init` (0.13 behaviour)
0 commit comments