pyfunction: better error message with `async fn`

This commit is contained in:
David Hewitt 2021-05-25 11:31:48 +01:00
parent b3946c3f78
commit 9f74336bc9
7 changed files with 39 additions and 1 deletions

View File

@ -8,7 +8,7 @@ use crate::{
deprecations::Deprecations,
method::{self, FnArg, FnSpec},
pymethod::{check_generic, get_arg_names, impl_arg_params},
utils,
utils::{self, ensure_not_async_fn},
};
use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote};
@ -349,6 +349,7 @@ pub fn impl_wrap_pyfunction(
options: PyFunctionOptions,
) -> syn::Result<(Ident, TokenStream)> {
check_generic(&func.sig)?;
ensure_not_async_fn(&func.sig)?;
let python_name = options
.name

View File

@ -1,3 +1,4 @@
use crate::utils::ensure_not_async_fn;
// Copyright (c) 2017-present PyO3 Project and Contributors
use crate::{attributes::FromPyWithAttribute, konst::ConstSpec};
use crate::{deprecations::Deprecations, utils};
@ -28,6 +29,7 @@ pub fn gen_py_method(
options: PyFunctionOptions,
) -> Result<GeneratedPyMethod> {
check_generic(sig)?;
ensure_not_async_fn(sig)?;
let spec = FnSpec::parse(sig, &mut *meth_attrs, options)?;
Ok(match &spec.tp {

View File

@ -164,3 +164,14 @@ pub fn get_doc(
Ok(syn::LitStr::new(&doc, span))
}
pub fn ensure_not_async_fn(sig: &syn::Signature) -> syn::Result<()> {
if let Some(asyncness) = &sig.asyncness {
bail_spanned!(
asyncness.span() => "`async fn` is not yet supported for Python functions.\n\n\
Additional crates such as `pyo3-asyncio` can be used to integrate async Rust and \
Python. For more information, see https://github.com/PyO3/pyo3/issues/1632"
);
};
Ok(())
}

View File

@ -6,4 +6,7 @@ fn generic_function<T>(value: T) {}
#[pyfunction]
fn impl_trait_function(impl_trait: impl AsRef<PyAny>) {}
#[pyfunction]
async fn async_function() {}
fn main() {}

View File

@ -9,3 +9,11 @@ error: Python functions cannot have `impl Trait` arguments
|
7 | fn impl_trait_function(impl_trait: impl AsRef<PyAny>) {}
| ^^^^
error: `async fn` is not yet supported for Python functions.
Additional crates such as `pyo3-asyncio` can be used to integrate async Rust and Python. For more information, see https://github.com/PyO3/pyo3/issues/1632
--> $DIR/invalid_pyfunctions.rs:10:1
|
10 | async fn async_function() {}
| ^^^^^

View File

@ -103,4 +103,9 @@ impl MyClass {
fn impl_trait_method_second_arg(&self, impl_trait: impl AsRef<PyAny>) {}
}
#[pymethods]
impl MyClass {
async fn async_method(&self) {}
}
fn main() {}

View File

@ -87,3 +87,11 @@ error: Python functions cannot have `impl Trait` arguments
|
103 | fn impl_trait_method_second_arg(&self, impl_trait: impl AsRef<PyAny>) {}
| ^^^^
error: `async fn` is not yet supported for Python functions.
Additional crates such as `pyo3-asyncio` can be used to integrate async Rust and Python. For more information, see https://github.com/PyO3/pyo3/issues/1632
--> $DIR/invalid_pymethods.rs:108:5
|
108 | async fn async_method(&self) {}
| ^^^^^