Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow easy async fn declaration for pyfunction #41

Open
ShadowJonathan opened this issue Aug 10, 2021 · 1 comment
Open

Allow easy async fn declaration for pyfunction #41

ShadowJonathan opened this issue Aug 10, 2021 · 1 comment

Comments

@ShadowJonathan
Copy link

To me, the current examples look very verbose for what they eventually do;

#[pyfunction]
fn sleep(py: Python) -> PyResult<&PyAny> {
    pyo3_asyncio::tokio::future_into_py(py, async move {
        let py_sleep = Python::with_gil(|py| {
            pyo3_asyncio::tokio::into_future(
                py.import("asyncio")?.call_method1("sleep", (1,))?
            )
        })?;

        py_sleep.await?;

        Ok(Python::with_gil(|py| py.None()))
    })
}

To me, this looks easily collapsible into something like this;

#[pyo3_asyncio::tokio::async_pyfunction]
async fn sleep() -> PyResult<&PyAny> {
    let py_sleep = Python::with_gil(|py| {
        pyo3_asyncio::tokio::into_future(
            py.import("asyncio")?.call_method1("sleep", (1,))?
        )
    })?;

    py_sleep.await?;

    Ok(Python::with_gil(|py| py.None()))
}

This would be a little bit more ergonomic to write.

@ShadowJonathan ShadowJonathan changed the title Allow easy async fn wrapper Allow easy async fn declaration for pyfunction Aug 10, 2021
@awestlake87
Copy link
Owner

awestlake87 commented Aug 10, 2021

Yeah, I was actually thinking about this again recently. I opened PyO3 PR 1406 awhile back to get my thoughts on it out there. The main issue I had with it at the time was that it would have been a bit weird to provide tokio specific or async-std specific stuff in the PyO3 core.

Moving that #[pyfunction] proc macro here would have been a lot of duplicated code and more than I wanted to maintain, but if we can instead delegate to #[pyfunction] from our own runtime-specific proc macro like you've laid out, then I think it would work better.

I think we can do something like this in the proc macro:

quote! {
    #[pyo3::pyfunction]
    fn #fn_signature {
        #entire_async_fn

        pyo3_asyncio::tokio::future_into_py(py, async move {
            #fn_name(#args).await
        })
    }
}

The main question is how much work do we have to do ourselves to get those variables in the proc macro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants