diff --git a/CHANGELOG.md b/CHANGELOG.md index 37fde44..8c35325 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ To see unreleased changes, please see the CHANGELOG on the main branch. `future_into_py` functions now require future return type to be `Send`. [#60](https://github.com/PyO3/pyo3-async-runtimes/pull/60) - Change pyo3 `downcast` calls to `cast` calls [#65](https://github.com/PyO3/pyo3-async-runtimes/pull/65) +- Use `pyo3::intern!` for method calls and `getattr` calls [#66](https://github.com/PyO3/pyo3-async-runtimes/pull/66) ## [0.26.0] - 2025-09-02 diff --git a/src/generic.rs b/src/generic.rs index 2440d96..df141fd 100644 --- a/src/generic.rs +++ b/src/generic.rs @@ -219,7 +219,7 @@ where }, )?; - event_loop.call_method1("run_until_complete", (coro,))?; + event_loop.call_method1(pyo3::intern!(py, "run_until_complete"), (coro,))?; let result = result_rx.lock().unwrap().take().unwrap(); Ok(result) @@ -316,7 +316,7 @@ where F: Future> + Send + 'static, T: Send + Sync + 'static, { - let event_loop = asyncio(py)?.call_method0("new_event_loop")?; + let event_loop = asyncio(py)?.call_method0(pyo3::intern!(py, "new_event_loop"))?; let result = run_until_complete::(&event_loop, fut); @@ -326,7 +326,10 @@ where } fn cancelled(future: &Bound) -> PyResult { - future.getattr("cancelled")?.call0()?.is_truthy() + future + .getattr(pyo3::intern!(future.py(), "cancelled"))? + .call0()? + .is_truthy() } #[pyclass] @@ -359,8 +362,14 @@ fn set_result( let none = py.None().into_bound(py); let (complete, val) = match result { - Ok(val) => (future.getattr("set_result")?, val.into_pyobject(py)?), - Err(err) => (future.getattr("set_exception")?, err.into_bound_py_any(py)?), + Ok(val) => ( + future.getattr(pyo3::intern!(py, "set_result"))?, + val.into_pyobject(py)?, + ), + Err(err) => ( + future.getattr(pyo3::intern!(py, "set_exception"))?, + err.into_bound_py_any(py)?, + ), }; call_soon_threadsafe(event_loop, &none, (CheckedCompletor, future, complete, val))?; @@ -608,7 +617,7 @@ where let py_fut = create_future(locals.0.event_loop.bind(py).clone())?; py_fut.call_method1( - "add_done_callback", + pyo3::intern!(py, "add_done_callback"), (PyDoneCallback { cancel_tx: Some(cancel_tx), },), @@ -1027,7 +1036,7 @@ where let py_fut = create_future(locals.0.event_loop.clone_ref(py).into_bound(py))?; py_fut.call_method1( - "add_done_callback", + pyo3::intern!(py, "add_done_callback"), (PyDoneCallback { cancel_tx: Some(cancel_tx), },), @@ -1345,7 +1354,8 @@ where R: Runtime, { let (tx, rx) = async_channel::bounded(1); - let anext: Py = gen.getattr("__anext__")?.into(); + let py = gen.py(); + let anext: Py = gen.getattr(pyo3::intern!(py, "__anext__"))?.into(); R::spawn(async move { loop { @@ -1716,11 +1726,13 @@ where let (tx, rx) = mpsc::channel(10); locals.event_loop(py).call_method1( - "call_soon_threadsafe", + pyo3::intern!(py, "call_soon_threadsafe"), ( - locals.event_loop(py).getattr("create_task")?, + locals + .event_loop(py) + .getattr(pyo3::intern!(py, "create_task"))?, glue.call_method1( - "forward", + pyo3::intern!(py, "forward"), ( gen, SenderGlue { diff --git a/src/lib.rs b/src/lib.rs index 9d35ebe..97e368a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -408,31 +408,34 @@ static GET_RUNNING_LOOP: PyOnceLock> = PyOnceLock::new(); fn ensure_future<'p>(py: Python<'p>, awaitable: &Bound<'p, PyAny>) -> PyResult> { ENSURE_FUTURE .get_or_try_init(py, || -> PyResult> { - Ok(asyncio(py)?.getattr("ensure_future")?.into()) + Ok(asyncio(py)? + .getattr(pyo3::intern!(py, "ensure_future"))? + .into()) })? .bind(py) .call1((awaitable,)) } fn create_future(event_loop: Bound<'_, PyAny>) -> PyResult> { - event_loop.call_method0("create_future") + event_loop.call_method0(pyo3::intern!(event_loop.py(), "create_future")) } fn close(event_loop: Bound) -> PyResult<()> { + let py = event_loop.py(); event_loop.call_method1( - "run_until_complete", - (event_loop.call_method0("shutdown_asyncgens")?,), + pyo3::intern!(py, "run_until_complete"), + (event_loop.call_method0(pyo3::intern!(py, "shutdown_asyncgens"))?,), )?; // how to do this prior to 3.9? - if event_loop.hasattr("shutdown_default_executor")? { + if event_loop.hasattr(pyo3::intern!(py, "shutdown_default_executor"))? { event_loop.call_method1( - "run_until_complete", - (event_loop.call_method0("shutdown_default_executor")?,), + pyo3::intern!(py, "run_until_complete"), + (event_loop.call_method0(pyo3::intern!(py, "shutdown_default_executor"))?,), )?; } - event_loop.call_method0("close")?; + event_loop.call_method0(pyo3::intern!(py, "close"))?; Ok(()) } @@ -453,7 +456,9 @@ pub fn get_running_loop(py: Python) -> PyResult> { .get_or_try_init(py, || -> PyResult> { let asyncio = asyncio(py)?; - Ok(asyncio.getattr("get_running_loop")?.into()) + Ok(asyncio + .getattr(pyo3::intern!(py, "get_running_loop"))? + .into()) })? .bind(py) .call0() @@ -466,7 +471,7 @@ fn contextvars(py: Python<'_>) -> PyResult<&Bound<'_, PyAny>> { } fn copy_context(py: Python) -> PyResult> { - contextvars(py)?.call_method0("copy_context") + contextvars(py)?.call_method0(pyo3::intern!(py, "copy_context")) } /// Task-local inner structure. @@ -543,8 +548,9 @@ struct PyTaskCompleter { impl PyTaskCompleter { #[pyo3(signature = (task))] pub fn __call__(&mut self, task: &Bound) -> PyResult<()> { - debug_assert!(task.call_method0("done")?.extract()?); - let result = match task.call_method0("result") { + let py = task.py(); + debug_assert!(task.call_method0(pyo3::intern!(py, "done"))?.extract()?); + let result = match task.call_method0(pyo3::intern!(py, "result")) { Ok(val) => Ok(val.into()), Err(e) => Err(e), }; @@ -575,7 +581,7 @@ impl PyEnsureFuture { Python::attach(|py| { let task = ensure_future(py, self.awaitable.bind(py))?; let on_complete = PyTaskCompleter { tx: self.tx.take() }; - task.call_method1("add_done_callback", (on_complete,))?; + task.call_method1(pyo3::intern!(py, "add_done_callback"), (on_complete,))?; Ok(()) }) @@ -590,9 +596,13 @@ fn call_soon_threadsafe<'py>( let py = event_loop.py(); let kwargs = PyDict::new(py); - kwargs.set_item("context", context)?; + kwargs.set_item(pyo3::intern!(py, "context"), context)?; - event_loop.call_method("call_soon_threadsafe", args, Some(&kwargs))?; + event_loop.call_method( + pyo3::intern!(py, "call_soon_threadsafe"), + args, + Some(&kwargs), + )?; Ok(()) } @@ -669,7 +679,7 @@ pub fn into_future_with_locals( Ok(item) => item, Err(_) => Python::attach(|py| { Err(PyErr::from_value( - asyncio(py)?.call_method0("CancelledError")?, + asyncio(py)?.call_method0(pyo3::intern!(py, "CancelledError"))?, )) }), }