pyo3_macros_backend/
deprecations.rs
1use crate::method::{FnArg, FnSpec};
2use proc_macro2::TokenStream;
3use quote::quote_spanned;
4
5pub(crate) fn deprecate_trailing_option_default(spec: &FnSpec<'_>) -> TokenStream {
6 if spec.signature.attribute.is_none()
7 && spec.tp.signature_attribute_allowed()
8 && spec.signature.arguments.iter().any(|arg| {
9 if let FnArg::Regular(arg) = arg {
10 arg.option_wrapped_type.is_some()
11 } else {
12 false
13 }
14 })
15 {
16 use std::fmt::Write;
17 let mut deprecation_msg = String::from(
18 "this function has implicit defaults for the trailing `Option<T>` arguments \n\
19 = note: these implicit defaults are being phased out \n\
20 = help: add `#[pyo3(signature = (",
21 );
22 spec.signature.arguments.iter().for_each(|arg| {
23 match arg {
24 FnArg::Regular(arg) => {
25 if arg.option_wrapped_type.is_some() {
26 write!(deprecation_msg, "{}=None, ", arg.name)
27 } else {
28 write!(deprecation_msg, "{}, ", arg.name)
29 }
30 }
31 FnArg::VarArgs(arg) => write!(deprecation_msg, "{}, ", arg.name),
32 FnArg::KwArgs(arg) => write!(deprecation_msg, "{}, ", arg.name),
33 FnArg::Py(_) | FnArg::CancelHandle(_) => Ok(()),
34 }
35 .expect("writing to `String` should not fail");
36 });
37
38 deprecation_msg.pop();
40 deprecation_msg.pop();
41
42 deprecation_msg.push_str(
43 "))]` to this function to silence this warning and keep the current behavior",
44 );
45 quote_spanned! { spec.name.span() =>
46 #[deprecated(note = #deprecation_msg)]
47 #[allow(dead_code)]
48 const SIGNATURE: () = ();
49 const _: () = SIGNATURE;
50 }
51 } else {
52 TokenStream::new()
53 }
54}