diff --git a/pyo3-macros-backend/src/frompyobject.rs b/pyo3-macros-backend/src/frompyobject.rs index d7767174e62..a20eeec9ffd 100644 --- a/pyo3-macros-backend/src/frompyobject.rs +++ b/pyo3-macros-backend/src/frompyobject.rs @@ -1,7 +1,7 @@ use crate::attributes::{self, get_pyo3_options, CrateAttribute, FromPyWithAttribute}; use crate::utils::Ctx; use proc_macro2::TokenStream; -use quote::{format_ident, quote, quote_spanned}; +use quote::{format_ident, quote}; use syn::{ parenthesized, parse::{Parse, ParseStream}, @@ -44,16 +44,14 @@ impl<'a> Enum<'a> { } /// Build derivation body for enums. - fn build(&self, ctx: &Ctx) -> (TokenStream, TokenStream) { + fn build(&self, ctx: &Ctx) -> TokenStream { let Ctx { pyo3_path, .. } = ctx; let mut var_extracts = Vec::new(); let mut variant_names = Vec::new(); let mut error_names = Vec::new(); - let mut deprecations = TokenStream::new(); for var in &self.variants { - let (struct_derive, dep) = var.build(ctx); - deprecations.extend(dep); + let struct_derive = var.build(ctx); let ext = quote!({ let maybe_ret = || -> #pyo3_path::PyResult { #struct_derive @@ -70,22 +68,19 @@ impl<'a> Enum<'a> { error_names.push(&var.err_name); } let ty_name = self.enum_ident.to_string(); - ( - quote!( - let errors = [ - #(#var_extracts),* - ]; - ::std::result::Result::Err( - #pyo3_path::impl_::frompyobject::failed_to_extract_enum( - obj.py(), - #ty_name, - &[#(#variant_names),*], - &[#(#error_names),*], - &errors - ) + quote!( + let errors = [ + #(#var_extracts),* + ]; + ::std::result::Result::Err( + #pyo3_path::impl_::frompyobject::failed_to_extract_enum( + obj.py(), + #ty_name, + &[#(#variant_names),*], + &[#(#error_names),*], + &errors ) - ), - deprecations, + ) ) } } @@ -244,7 +239,7 @@ impl<'a> Container<'a> { } /// Build derivation body for a struct. - fn build(&self, ctx: &Ctx) -> (TokenStream, TokenStream) { + fn build(&self, ctx: &Ctx) -> TokenStream { match &self.ty { ContainerType::StructNewtype(ident, from_py_with) => { self.build_newtype_struct(Some(ident), from_py_with, ctx) @@ -262,73 +257,42 @@ impl<'a> Container<'a> { field_ident: Option<&Ident>, from_py_with: &Option, ctx: &Ctx, - ) -> (TokenStream, TokenStream) { + ) -> TokenStream { let Ctx { pyo3_path, .. } = ctx; let self_ty = &self.path; let struct_name = self.name(); if let Some(ident) = field_ident { let field_name = ident.to_string(); match from_py_with { - None => ( - quote! { - Ok(#self_ty { - #ident: #pyo3_path::impl_::frompyobject::extract_struct_field(obj, #struct_name, #field_name)? - }) - }, - TokenStream::new(), - ), + None => quote! { + Ok(#self_ty { + #ident: #pyo3_path::impl_::frompyobject::extract_struct_field(obj, #struct_name, #field_name)? + }) + }, Some(FromPyWithAttribute { value: expr_path, .. - }) => ( - quote! { - Ok(#self_ty { - #ident: #pyo3_path::impl_::frompyobject::extract_struct_field_with(#expr_path as fn(_) -> _, obj, #struct_name, #field_name)? - }) - }, - quote_spanned! { expr_path.span() => - const _: () = { - fn check_from_py_with() { - let e = #pyo3_path::impl_::deprecations::GilRefs::new(); - #pyo3_path::impl_::deprecations::inspect_fn(#expr_path, &e); - e.from_py_with_arg(); - } - }; - }, - ), + }) => quote! { + Ok(#self_ty { + #ident: #pyo3_path::impl_::frompyobject::extract_struct_field_with(#expr_path as fn(_) -> _, obj, #struct_name, #field_name)? + }) + }, } } else { match from_py_with { - None => ( - quote!( - #pyo3_path::impl_::frompyobject::extract_tuple_struct_field(obj, #struct_name, 0).map(#self_ty) - ), - TokenStream::new(), - ), + None => quote! { + #pyo3_path::impl_::frompyobject::extract_tuple_struct_field(obj, #struct_name, 0).map(#self_ty) + }, + Some(FromPyWithAttribute { value: expr_path, .. - }) => ( - quote! ( - #pyo3_path::impl_::frompyobject::extract_tuple_struct_field_with(#expr_path as fn(_) -> _, obj, #struct_name, 0).map(#self_ty) - ), - quote_spanned! { expr_path.span() => - const _: () = { - fn check_from_py_with() { - let e = #pyo3_path::impl_::deprecations::GilRefs::new(); - #pyo3_path::impl_::deprecations::inspect_fn(#expr_path, &e); - e.from_py_with_arg(); - } - }; - }, - ), + }) => quote! { + #pyo3_path::impl_::frompyobject::extract_tuple_struct_field_with(#expr_path as fn(_) -> _, obj, #struct_name, 0).map(#self_ty) + }, } } } - fn build_tuple_struct( - &self, - struct_fields: &[TupleStructField], - ctx: &Ctx, - ) -> (TokenStream, TokenStream) { + fn build_tuple_struct(&self, struct_fields: &[TupleStructField], ctx: &Ctx) -> TokenStream { let Ctx { pyo3_path, .. } = ctx; let self_ty = &self.path; let struct_name = &self.name(); @@ -348,40 +312,15 @@ impl<'a> Container<'a> { } }); - let deprecations = struct_fields - .iter() - .filter_map(|field| { - let FromPyWithAttribute { - value: expr_path, .. - } = field.from_py_with.as_ref()?; - Some(quote_spanned! { expr_path.span() => - const _: () = { - fn check_from_py_with() { - let e = #pyo3_path::impl_::deprecations::GilRefs::new(); - #pyo3_path::impl_::deprecations::inspect_fn(#expr_path, &e); - e.from_py_with_arg(); - } - }; - }) - }) - .collect::(); - - ( - quote!( - match #pyo3_path::types::PyAnyMethods::extract(obj) { - ::std::result::Result::Ok((#(#field_idents),*)) => ::std::result::Result::Ok(#self_ty(#(#fields),*)), - ::std::result::Result::Err(err) => ::std::result::Result::Err(err), - } - ), - deprecations, + quote!( + match #pyo3_path::types::PyAnyMethods::extract(obj) { + ::std::result::Result::Ok((#(#field_idents),*)) => ::std::result::Result::Ok(#self_ty(#(#fields),*)), + ::std::result::Result::Err(err) => ::std::result::Result::Err(err), + } ) } - fn build_struct( - &self, - struct_fields: &[NamedStructField<'_>], - ctx: &Ctx, - ) -> (TokenStream, TokenStream) { + fn build_struct(&self, struct_fields: &[NamedStructField<'_>], ctx: &Ctx) -> TokenStream { let Ctx { pyo3_path, .. } = ctx; let self_ty = &self.path; let struct_name = &self.name(); @@ -420,28 +359,7 @@ impl<'a> Container<'a> { fields.push(quote!(#ident: #extractor)); } - let deprecations = struct_fields - .iter() - .filter_map(|field| { - let FromPyWithAttribute { - value: expr_path, .. - } = field.from_py_with.as_ref()?; - Some(quote_spanned! { expr_path.span() => - const _: () = { - fn check_from_py_with() { - let e = #pyo3_path::impl_::deprecations::GilRefs::new(); - #pyo3_path::impl_::deprecations::inspect_fn(#expr_path, &e); - e.from_py_with_arg(); - } - }; - }) - }) - .collect::(); - - ( - quote!(::std::result::Result::Ok(#self_ty{#fields})), - deprecations, - ) + quote!(::std::result::Result::Ok(#self_ty{#fields})) } } @@ -673,7 +591,7 @@ pub fn build_derive_from_pyobject(tokens: &DeriveInput) -> Result { let ctx = &Ctx::new(&options.krate, None); let Ctx { pyo3_path, .. } = &ctx; - let (derives, from_py_with_deprecations) = match &tokens.data { + let derives = match &tokens.data { syn::Data::Enum(en) => { if options.transparent || options.annotation.is_some() { bail_spanned!(tokens.span() => "`transparent` or `annotation` is not supported \ @@ -703,7 +621,5 @@ pub fn build_derive_from_pyobject(tokens: &DeriveInput) -> Result { #derives } } - - #from_py_with_deprecations )) } diff --git a/pyo3-macros-backend/src/method.rs b/pyo3-macros-backend/src/method.rs index 0d00f952f6c..3efcc3e9967 100644 --- a/pyo3-macros-backend/src/method.rs +++ b/pyo3-macros-backend/src/method.rs @@ -683,11 +683,10 @@ impl<'a> FnSpec<'a> { } _ => { if let Some(self_arg) = self_arg() { - let self_checker = holders.push_gil_refs_checker(self_arg.span()); quote! { function( // NB #self_arg includes a comma, so none inserted here - #pyo3_path::impl_::deprecations::inspect_type(#self_arg &#self_checker), + #self_arg #(#args),* ) } @@ -714,11 +713,10 @@ impl<'a> FnSpec<'a> { } call } else if let Some(self_arg) = self_arg() { - let self_checker = holders.push_gil_refs_checker(self_arg.span()); quote! { function( // NB #self_arg includes a comma, so none inserted here - #pyo3_path::impl_::deprecations::inspect_type(#self_arg &#self_checker), + #self_arg #(#args),* ) } @@ -762,7 +760,6 @@ impl<'a> FnSpec<'a> { }) .collect(); let call = rust_call(args, &mut holders); - let check_gil_refs = holders.check_gil_refs(); let init_holders = holders.init_holders(ctx); quote! { unsafe fn #ident<'py>( @@ -774,7 +771,6 @@ impl<'a> FnSpec<'a> { let function = #rust_name; // Shadow the function name to avoid #3017 #init_holders let result = #call; - #check_gil_refs result } } @@ -784,7 +780,6 @@ impl<'a> FnSpec<'a> { let (arg_convert, args) = impl_arg_params(self, cls, true, &mut holders, ctx); let call = rust_call(args, &mut holders); let init_holders = holders.init_holders(ctx); - let check_gil_refs = holders.check_gil_refs(); quote! { unsafe fn #ident<'py>( @@ -800,7 +795,6 @@ impl<'a> FnSpec<'a> { #arg_convert #init_holders let result = #call; - #check_gil_refs result } } @@ -810,7 +804,6 @@ impl<'a> FnSpec<'a> { let (arg_convert, args) = impl_arg_params(self, cls, false, &mut holders, ctx); let call = rust_call(args, &mut holders); let init_holders = holders.init_holders(ctx); - let check_gil_refs = holders.check_gil_refs(); quote! { unsafe fn #ident<'py>( @@ -825,7 +818,6 @@ impl<'a> FnSpec<'a> { #arg_convert #init_holders let result = #call; - #check_gil_refs result } } @@ -838,7 +830,6 @@ impl<'a> FnSpec<'a> { .self_arg(cls, ExtractErrorMode::Raise, &mut holders, ctx); let call = quote_spanned! {*output_span=> #rust_name(#self_arg #(#args),*) }; let init_holders = holders.init_holders(ctx); - let check_gil_refs = holders.check_gil_refs(); quote! { unsafe fn #ident( py: #pyo3_path::Python<'_>, @@ -854,7 +845,6 @@ impl<'a> FnSpec<'a> { #init_holders let result = #call; let initializer: #pyo3_path::PyClassInitializer::<#cls> = result.convert(py)?; - #check_gil_refs #pyo3_path::impl_::pymethods::tp_new_impl(py, initializer, _slf) } } diff --git a/pyo3-macros-backend/src/module.rs b/pyo3-macros-backend/src/module.rs index 2ca084a6a4b..26e3816c8c4 100644 --- a/pyo3-macros-backend/src/module.rs +++ b/pyo3-macros-backend/src/module.rs @@ -16,7 +16,7 @@ use std::ffi::CString; use syn::{ ext::IdentExt, parse::{Parse, ParseStream}, - parse_quote, parse_quote_spanned, + parse_quote, punctuated::Punctuated, spanned::Spanned, token::Comma, @@ -377,7 +377,6 @@ pub fn pymodule_function_impl(mut function: syn::ItemFn) -> Result let options = PyModuleOptions::from_attrs(&mut function.attrs)?; process_functions_in_module(&options, &mut function)?; let ctx = &Ctx::new(&options.krate, None); - let stmts = std::mem::take(&mut function.block.stmts); let Ctx { pyo3_path, .. } = ctx; let ident = &function.sig.ident; let name = options.name.unwrap_or_else(|| ident.unraw()); @@ -394,30 +393,6 @@ pub fn pymodule_function_impl(mut function: syn::ItemFn) -> Result module_args .push(quote!(::std::convert::Into::into(#pyo3_path::impl_::pymethods::BoundRef(module)))); - let extractors = function - .sig - .inputs - .iter() - .filter_map(|param| { - if let syn::FnArg::Typed(pat_type) = param { - if let syn::Pat::Ident(pat_ident) = &*pat_type.pat { - let ident: &syn::Ident = &pat_ident.ident; - return Some([ - parse_quote!{ let check_gil_refs = #pyo3_path::impl_::deprecations::GilRefs::new(); }, - parse_quote! { let #ident = #pyo3_path::impl_::deprecations::inspect_type(#ident, &check_gil_refs); }, - parse_quote_spanned! { pat_type.span() => check_gil_refs.function_arg(); }, - ]); - } - } - None - }) - .flatten(); - - function.block.stmts = extractors.chain(stmts).collect(); - function - .attrs - .push(parse_quote!(#[allow(clippy::used_underscore_binding)])); - Ok(quote! { #function #[doc(hidden)] diff --git a/pyo3-macros-backend/src/params.rs b/pyo3-macros-backend/src/params.rs index f7d71b923a6..ccf725d3760 100644 --- a/pyo3-macros-backend/src/params.rs +++ b/pyo3-macros-backend/src/params.rs @@ -10,14 +10,12 @@ use syn::spanned::Spanned; pub struct Holders { holders: Vec, - gil_refs_checkers: Vec, } impl Holders { pub fn new() -> Self { Holders { holders: Vec::new(), - gil_refs_checkers: Vec::new(), } } @@ -27,58 +25,14 @@ impl Holders { holder } - pub fn push_gil_refs_checker(&mut self, span: Span) -> syn::Ident { - let gil_refs_checker = syn::Ident::new( - &format!("gil_refs_checker_{}", self.gil_refs_checkers.len()), - span, - ); - self.gil_refs_checkers - .push(GilRefChecker::FunctionArg(gil_refs_checker.clone())); - gil_refs_checker - } - - pub fn push_from_py_with_checker(&mut self, span: Span) -> syn::Ident { - let gil_refs_checker = syn::Ident::new( - &format!("gil_refs_checker_{}", self.gil_refs_checkers.len()), - span, - ); - self.gil_refs_checkers - .push(GilRefChecker::FromPyWith(gil_refs_checker.clone())); - gil_refs_checker - } - pub fn init_holders(&self, ctx: &Ctx) -> TokenStream { let Ctx { pyo3_path, .. } = ctx; let holders = &self.holders; - let gil_refs_checkers = self.gil_refs_checkers.iter().map(|checker| match checker { - GilRefChecker::FunctionArg(ident) => ident, - GilRefChecker::FromPyWith(ident) => ident, - }); quote! { #[allow(clippy::let_unit_value)] #(let mut #holders = #pyo3_path::impl_::extract_argument::FunctionArgumentHolder::INIT;)* - #(let #gil_refs_checkers = #pyo3_path::impl_::deprecations::GilRefs::new();)* } } - - pub fn check_gil_refs(&self) -> TokenStream { - self.gil_refs_checkers - .iter() - .map(|checker| match checker { - GilRefChecker::FunctionArg(ident) => { - quote_spanned! { ident.span() => #ident.function_arg(); } - } - GilRefChecker::FromPyWith(ident) => { - quote_spanned! { ident.span() => #ident.from_py_with_arg(); } - } - }) - .collect() - } -} - -enum GilRefChecker { - FunctionArg(syn::Ident), - FromPyWith(syn::Ident), } /// Return true if the argument list is simply (*args, **kwds). @@ -89,17 +43,6 @@ pub fn is_forwarded_args(signature: &FunctionSignature<'_>) -> bool { ) } -pub(crate) fn check_arg_for_gil_refs( - tokens: TokenStream, - gil_refs_checker: syn::Ident, - ctx: &Ctx, -) -> TokenStream { - let Ctx { pyo3_path, .. } = ctx; - quote! { - #pyo3_path::impl_::deprecations::inspect_type(#tokens, &#gil_refs_checker) - } -} - pub fn impl_arg_params( spec: &FnSpec<'_>, self_: Option<&syn::Type>, @@ -119,9 +62,7 @@ pub fn impl_arg_params( let from_py_with = &arg.from_py_with()?.value; let from_py_with_holder = format_ident!("from_py_with_{}", i); Some(quote_spanned! { from_py_with.span() => - let e = #pyo3_path::impl_::deprecations::GilRefs::new(); - let #from_py_with_holder = #pyo3_path::impl_::deprecations::inspect_fn(#from_py_with, &e); - e.from_py_with_arg(); + let #from_py_with_holder = #from_py_with; }) }) .collect::(); @@ -250,8 +191,7 @@ fn impl_arg_param( let from_py_with = format_ident!("from_py_with_{}", pos); let arg_value = quote!(#args_array[#option_pos].as_deref()); *option_pos += 1; - let tokens = impl_regular_arg_param(arg, from_py_with, arg_value, holders, ctx); - check_arg_for_gil_refs(tokens, holders.push_gil_refs_checker(arg.ty.span()), ctx) + impl_regular_arg_param(arg, from_py_with, arg_value, holders, ctx) } FnArg::VarArgs(arg) => { let holder = holders.push_holder(arg.name.span()); diff --git a/pyo3-macros-backend/src/pymethod.rs b/pyo3-macros-backend/src/pymethod.rs index 7a9afa54755..c02599903e1 100644 --- a/pyo3-macros-backend/src/pymethod.rs +++ b/pyo3-macros-backend/src/pymethod.rs @@ -4,7 +4,7 @@ use std::ffi::CString; use crate::attributes::{NameAttribute, RenamingRule}; use crate::deprecations::deprecate_trailing_option_default; use crate::method::{CallingConvention, ExtractErrorMode, PyArg}; -use crate::params::{check_arg_for_gil_refs, impl_regular_arg_param, Holders}; +use crate::params::{impl_regular_arg_param, Holders}; use crate::utils::PythonDoc; use crate::utils::{Ctx, LitCStr}; use crate::{ @@ -612,21 +612,18 @@ pub fn impl_py_setter_def( PropertyType::Function { spec, .. } => { let (_, args) = split_off_python_arg(&spec.signature.arguments); let value_arg = &args[0]; - let (from_py_with, ident) = if let Some(from_py_with) = - &value_arg.from_py_with().as_ref().map(|f| &f.value) - { - let ident = syn::Ident::new("from_py_with", from_py_with.span()); - ( - quote_spanned! { from_py_with.span() => - let e = #pyo3_path::impl_::deprecations::GilRefs::new(); - let #ident = #pyo3_path::impl_::deprecations::inspect_fn(#from_py_with, &e); - e.from_py_with_arg(); - }, - ident, - ) - } else { - (quote!(), syn::Ident::new("dummy", Span::call_site())) - }; + let (from_py_with, ident) = + if let Some(from_py_with) = &value_arg.from_py_with().as_ref().map(|f| &f.value) { + let ident = syn::Ident::new("from_py_with", from_py_with.span()); + ( + quote_spanned! { from_py_with.span() => + let #ident = #from_py_with; + }, + ident, + ) + } else { + (quote!(), syn::Ident::new("dummy", Span::call_site())) + }; let arg = if let FnArg::Regular(arg) = &value_arg { arg @@ -634,15 +631,13 @@ pub fn impl_py_setter_def( bail_spanned!(value_arg.name().span() => "The #[setter] value argument can't be *args, **kwargs or `cancel_handle`."); }; - let tokens = impl_regular_arg_param( + let extract = impl_regular_arg_param( arg, ident, quote!(::std::option::Option::Some(_value.into())), &mut holders, ctx, ); - let extract = - check_arg_for_gil_refs(tokens, holders.push_gil_refs_checker(arg.ty.span()), ctx); let deprecation = deprecate_trailing_option_default(spec); quote! { @@ -660,12 +655,8 @@ pub fn impl_py_setter_def( .unwrap_or_default(); let holder = holders.push_holder(span); - let gil_refs_checker = holders.push_gil_refs_checker(span); quote! { - let _val = #pyo3_path::impl_::deprecations::inspect_type( - #pyo3_path::impl_::extract_argument::extract_argument(_value.into(), &mut #holder, #name)?, - &#gil_refs_checker - ); + let _val = #pyo3_path::impl_::extract_argument::extract_argument(_value.into(), &mut #holder, #name)?; } } }; @@ -682,7 +673,6 @@ pub fn impl_py_setter_def( } let init_holders = holders.init_holders(ctx); - let check_gil_refs = holders.check_gil_refs(); let associated_method = quote! { #cfg_attrs unsafe fn #wrapper_ident( @@ -698,7 +688,6 @@ pub fn impl_py_setter_def( #init_holders #extract let result = #setter_impl; - #check_gil_refs #pyo3_path::callback::convert(py, result) } }; @@ -824,7 +813,6 @@ pub fn impl_py_getter_def( }; let init_holders = holders.init_holders(ctx); - let check_gil_refs = holders.check_gil_refs(); let associated_method = quote! { #cfg_attrs unsafe fn #wrapper_ident( @@ -833,7 +821,6 @@ pub fn impl_py_getter_def( ) -> #pyo3_path::PyResult<*mut #pyo3_path::ffi::PyObject> { #init_holders let result = #body; - #check_gil_refs result } }; @@ -1139,35 +1126,30 @@ fn extract_object( ctx: &Ctx, ) -> TokenStream { let Ctx { pyo3_path, .. } = ctx; - let gil_refs_checker = holders.push_gil_refs_checker(arg.ty().span()); let name = arg.name().unraw().to_string(); - let extract = if let Some(from_py_with) = - arg.from_py_with().map(|from_py_with| &from_py_with.value) - { - let from_py_with_checker = holders.push_from_py_with_checker(from_py_with.span()); - quote! { - #pyo3_path::impl_::extract_argument::from_py_with( - #pyo3_path::impl_::pymethods::BoundRef::ref_from_ptr(py, &#source_ptr).0, - #name, - #pyo3_path::impl_::deprecations::inspect_fn(#from_py_with, &#from_py_with_checker) as fn(_) -> _, - ) - } - } else { - let holder = holders.push_holder(Span::call_site()); - quote! { - #pyo3_path::impl_::extract_argument::extract_argument( - #pyo3_path::impl_::pymethods::BoundRef::ref_from_ptr(py, &#source_ptr).0, - &mut #holder, - #name - ) - } - }; + let extract = + if let Some(from_py_with) = arg.from_py_with().map(|from_py_with| &from_py_with.value) { + quote! { + #pyo3_path::impl_::extract_argument::from_py_with( + #pyo3_path::impl_::pymethods::BoundRef::ref_from_ptr(py, &#source_ptr).0, + #name, + #from_py_with as fn(_) -> _, + ) + } + } else { + let holder = holders.push_holder(Span::call_site()); + quote! { + #pyo3_path::impl_::extract_argument::extract_argument( + #pyo3_path::impl_::pymethods::BoundRef::ref_from_ptr(py, &#source_ptr).0, + &mut #holder, + #name + ) + } + }; let extracted = extract_error_mode.handle_error(extract, ctx); - quote! { - #pyo3_path::impl_::deprecations::inspect_type(#extracted, &#gil_refs_checker) - } + quote!(#extracted) } enum ReturnMode { @@ -1177,15 +1159,13 @@ enum ReturnMode { } impl ReturnMode { - fn return_call_output(&self, call: TokenStream, ctx: &Ctx, holders: &Holders) -> TokenStream { + fn return_call_output(&self, call: TokenStream, ctx: &Ctx) -> TokenStream { let Ctx { pyo3_path, .. } = ctx; - let check_gil_refs = holders.check_gil_refs(); match self { ReturnMode::Conversion(conversion) => { let conversion = TokenGeneratorCtx(*conversion, ctx); quote! { let _result: #pyo3_path::PyResult<#conversion> = #pyo3_path::callback::convert(py, #call); - #check_gil_refs #pyo3_path::callback::convert(py, _result) } } @@ -1195,14 +1175,12 @@ impl ReturnMode { quote! { let _result = #call; use #pyo3_path::impl_::pymethods::{#traits}; - #check_gil_refs (&_result).#tag().convert(py, _result) } } ReturnMode::ReturnSelf => quote! { let _result: #pyo3_path::PyResult<()> = #pyo3_path::callback::convert(py, #call); _result?; - #check_gil_refs #pyo3_path::ffi::Py_XINCREF(_raw_slf); ::std::result::Result::Ok(_raw_slf) }, @@ -1369,12 +1347,10 @@ fn generate_method_body( let args = extract_proto_arguments(spec, arguments, extract_error_mode, holders, ctx)?; let call = quote! { #cls::#rust_name(#self_arg #(#args),*) }; Ok(if let Some(return_mode) = return_mode { - return_mode.return_call_output(call, ctx, holders) + return_mode.return_call_output(call, ctx) } else { - let check_gil_refs = holders.check_gil_refs(); quote! { let result = #call; - #check_gil_refs; #pyo3_path::callback::convert(py, result) } }) diff --git a/src/impl_/deprecations.rs b/src/impl_/deprecations.rs index eb5caa8dffb..6b9930ac69b 100644 --- a/src/impl_/deprecations.rs +++ b/src/impl_/deprecations.rs @@ -1,76 +1,4 @@ //! Symbols used to denote deprecated usages of PyO3's proc macros. -use crate::{PyResult, Python}; - #[deprecated(since = "0.20.0", note = "use `#[new]` instead of `#[__new__]`")] pub const PYMETHODS_NEW_DEPRECATED_FORM: () = (); - -pub fn inspect_type(t: T, _: &GilRefs) -> T { - t -} - -pub fn inspect_fn(f: fn(A) -> PyResult, _: &GilRefs) -> fn(A) -> PyResult { - f -} - -pub struct GilRefs(OptionGilRefs); -pub struct OptionGilRefs(NotAGilRef); -pub struct NotAGilRef(std::marker::PhantomData); - -pub trait IsGilRef {} - -#[cfg(feature = "gil-refs")] -impl IsGilRef for &'_ T {} - -impl GilRefs { - #[allow(clippy::new_without_default)] - pub fn new() -> Self { - GilRefs(OptionGilRefs(NotAGilRef(std::marker::PhantomData))) - } -} - -impl GilRefs> { - #[deprecated(since = "0.21.0", note = "use `wrap_pyfunction_bound!` instead")] - pub fn is_python(&self) {} -} - -impl GilRefs { - #[deprecated( - since = "0.21.0", - note = "use `&Bound<'_, T>` instead for this function argument" - )] - pub fn function_arg(&self) {} - #[deprecated( - since = "0.21.0", - note = "use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor" - )] - pub fn from_py_with_arg(&self) {} -} - -impl OptionGilRefs> { - #[deprecated( - since = "0.21.0", - note = "use `Option<&Bound<'_, T>>` instead for this function argument" - )] - pub fn function_arg(&self) {} -} - -impl NotAGilRef { - pub fn function_arg(&self) {} - pub fn from_py_with_arg(&self) {} - pub fn is_python(&self) {} -} - -impl std::ops::Deref for GilRefs { - type Target = OptionGilRefs; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl std::ops::Deref for OptionGilRefs { - type Target = NotAGilRef; - fn deref(&self) -> &Self::Target { - &self.0 - } -} diff --git a/src/macros.rs b/src/macros.rs index ab91d577ac5..43fbef12b89 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -145,12 +145,8 @@ macro_rules! wrap_pyfunction { }; ($function:path, $py_or_module:expr) => {{ use $function as wrapped_pyfunction; - let check_gil_refs = $crate::impl_::deprecations::GilRefs::new(); - let py_or_module = - $crate::impl_::deprecations::inspect_type($py_or_module, &check_gil_refs); - check_gil_refs.is_python(); $crate::impl_::pyfunction::WrapPyFunctionArg::wrap_pyfunction( - py_or_module, + $py_or_module, &wrapped_pyfunction::_PYO3_DEF, ) }}; diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 9e8b3b1a593..bdfc4893ed1 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -20,7 +20,6 @@ fn test_compile_errors() { t.compile_fail("tests/ui/invalid_pymethod_names.rs"); t.compile_fail("tests/ui/invalid_pymodule_args.rs"); t.compile_fail("tests/ui/reject_generics.rs"); - #[cfg(feature = "gil-refs")] t.compile_fail("tests/ui/deprecations.rs"); t.compile_fail("tests/ui/invalid_closure.rs"); t.compile_fail("tests/ui/pyclass_send.rs"); diff --git a/tests/ui/deprecations.rs b/tests/ui/deprecations.rs index ff34966e00d..97ad6629f2f 100644 --- a/tests/ui/deprecations.rs +++ b/tests/ui/deprecations.rs @@ -2,7 +2,6 @@ #![allow(dead_code)] use pyo3::prelude::*; -use pyo3::types::{PyString, PyType}; #[pyclass] struct MyClass; @@ -13,114 +12,14 @@ impl MyClass { fn new() -> Self { Self } - - #[classmethod] - fn cls_method_gil_ref(_cls: &PyType) {} - - #[classmethod] - fn cls_method_bound(_cls: &Bound<'_, PyType>) {} - - fn method_gil_ref(_slf: &PyCell) {} - - fn method_bound(_slf: &Bound<'_, Self>) {} - - #[staticmethod] - fn static_method_gil_ref(_any: &PyAny) {} - - #[setter] - fn set_foo_gil_ref(&self, #[pyo3(from_py_with = "extract_gil_ref")] _value: i32) {} - - #[setter] - fn set_foo_bound(&self, #[pyo3(from_py_with = "extract_bound")] _value: i32) {} - - #[setter] - fn set_bar_gil_ref(&self, _value: &PyAny) {} - - #[setter] - fn set_bar_bound(&self, _value: &Bound<'_, PyAny>) {} - - fn __eq__(&self, #[pyo3(from_py_with = "extract_gil_ref")] _other: i32) -> bool { - true - } - - fn __contains__(&self, #[pyo3(from_py_with = "extract_bound")] _value: i32) -> bool { - true - } } fn main() {} -#[pyfunction] -#[pyo3(pass_module)] -fn pyfunction_with_module<'py>(module: &Bound<'py, PyModule>) -> PyResult> { - module.name() -} - -#[pyfunction] -#[pyo3(pass_module)] -fn pyfunction_with_module_gil_ref(_module: &PyModule) -> PyResult<&str> { - todo!() -} - -#[pyfunction] -fn double(x: usize) -> usize { - x * 2 -} - -#[pymodule] -fn module_gil_ref(_m: &PyModule) -> PyResult<()> { - Ok(()) -} - -#[pymodule] -fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, _m: &PyModule) -> PyResult<()> { - Ok(()) -} - -#[pymodule] -fn module_bound(m: &Bound<'_, PyModule>) -> PyResult<()> { - m.add_function(wrap_pyfunction!(double, m)?)?; - Ok(()) -} - -#[pymodule] -fn module_bound_with_explicit_py_arg(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> { - m.add_function(wrap_pyfunction!(double, m)?)?; - Ok(()) -} - -#[pymodule] -fn module_bound_by_value(m: Bound<'_, PyModule>) -> PyResult<()> { - m.add_function(wrap_pyfunction!(double, &m)?)?; - Ok(()) -} - -fn extract_gil_ref(obj: &PyAny) -> PyResult { - obj.extract() -} - -fn extract_bound(obj: &Bound<'_, PyAny>) -> PyResult { - obj.extract() -} - fn extract_options(obj: &Bound<'_, PyAny>) -> PyResult> { obj.extract() } -#[pyfunction] -fn pyfunction_from_py_with( - #[pyo3(from_py_with = "extract_gil_ref")] _gil_ref: i32, - #[pyo3(from_py_with = "extract_bound")] _bound: i32, -) { -} - -#[pyfunction] -fn pyfunction_gil_ref(_any: &PyAny) {} - -#[pyfunction] -#[pyo3(signature = (_any))] -fn pyfunction_option_gil_ref(_any: Option<&PyAny>) {} - #[pyfunction] #[pyo3(signature = (_i, _any=None))] fn pyfunction_option_1(_i: u32, _any: Option) {} @@ -139,61 +38,6 @@ fn pyfunction_option_4( ) { } -#[derive(Debug, FromPyObject)] -pub struct Zap { - #[pyo3(item)] - name: String, - - #[pyo3(from_py_with = "PyAny::len", item("my_object"))] - some_object_length: usize, - - #[pyo3(from_py_with = "extract_bound")] - some_number: i32, -} - -#[derive(Debug, FromPyObject)] -pub struct ZapTuple( - String, - #[pyo3(from_py_with = "PyAny::len")] usize, - #[pyo3(from_py_with = "extract_bound")] i32, -); - -#[derive(Debug, FromPyObject, PartialEq, Eq)] -pub enum ZapEnum { - Zip(#[pyo3(from_py_with = "extract_gil_ref")] i32), - Zap(String, #[pyo3(from_py_with = "extract_bound")] i32), -} - -#[derive(Debug, FromPyObject, PartialEq, Eq)] -#[pyo3(transparent)] -pub struct TransparentFromPyWithGilRef { - #[pyo3(from_py_with = "extract_gil_ref")] - len: i32, -} - -#[derive(Debug, FromPyObject, PartialEq, Eq)] -#[pyo3(transparent)] -pub struct TransparentFromPyWithBound { - #[pyo3(from_py_with = "extract_bound")] - len: i32, -} - -fn test_wrap_pyfunction(py: Python<'_>, m: &Bound<'_, PyModule>) { - // should lint - let _ = wrap_pyfunction!(double, py); - - // should lint but currently does not - let _ = wrap_pyfunction!(double)(py); - - // should not lint - let _ = wrap_pyfunction!(double, m); - let _ = wrap_pyfunction!(double)(m); - let _ = wrap_pyfunction!(double, m.as_gil_ref()); - let _ = wrap_pyfunction!(double)(m.as_gil_ref()); - let _ = wrap_pyfunction_bound!(double, py); - let _ = wrap_pyfunction_bound!(double)(py); -} - #[pyclass] pub enum SimpleEnumWithoutEq { VariamtA, diff --git a/tests/ui/deprecations.stderr b/tests/ui/deprecations.stderr index 4f1797da838..f9e9652e377 100644 --- a/tests/ui/deprecations.stderr +++ b/tests/ui/deprecations.stderr @@ -1,7 +1,7 @@ error: use of deprecated constant `pyo3::deprecations::PYMETHODS_NEW_DEPRECATED_FORM`: use `#[new]` instead of `#[__new__]` - --> tests/ui/deprecations.rs:12:7 + --> tests/ui/deprecations.rs:11:7 | -12 | #[__new__] +11 | #[__new__] | ^^^^^^^ | note: the lint level is defined here @@ -13,141 +13,31 @@ note: the lint level is defined here error: use of deprecated constant `__pyfunction_pyfunction_option_2::SIGNATURE`: this function has implicit defaults for the trailing `Option` arguments = note: these implicit defaults are being phased out = help: add `#[pyo3(signature = (_i, _any=None))]` to this function to silence this warning and keep the current behavior - --> tests/ui/deprecations.rs:129:4 - | -129 | fn pyfunction_option_2(_i: u32, _any: Option) {} - | ^^^^^^^^^^^^^^^^^^^ + --> tests/ui/deprecations.rs:28:4 + | +28 | fn pyfunction_option_2(_i: u32, _any: Option) {} + | ^^^^^^^^^^^^^^^^^^^ error: use of deprecated constant `__pyfunction_pyfunction_option_3::SIGNATURE`: this function has implicit defaults for the trailing `Option` arguments = note: these implicit defaults are being phased out = help: add `#[pyo3(signature = (_i, _any=None, _foo=None))]` to this function to silence this warning and keep the current behavior - --> tests/ui/deprecations.rs:132:4 - | -132 | fn pyfunction_option_3(_i: u32, _any: Option, _foo: Option) {} - | ^^^^^^^^^^^^^^^^^^^ + --> tests/ui/deprecations.rs:31:4 + | +31 | fn pyfunction_option_3(_i: u32, _any: Option, _foo: Option) {} + | ^^^^^^^^^^^^^^^^^^^ error: use of deprecated constant `__pyfunction_pyfunction_option_4::SIGNATURE`: this function has implicit defaults for the trailing `Option` arguments = note: these implicit defaults are being phased out = help: add `#[pyo3(signature = (_i, _any=None, _foo=None))]` to this function to silence this warning and keep the current behavior - --> tests/ui/deprecations.rs:135:4 - | -135 | fn pyfunction_option_4( - | ^^^^^^^^^^^^^^^^^^^ - -error: use of deprecated constant `SimpleEnumWithoutEq::__pyo3__generated____richcmp__::DEPRECATION`: Implicit equality for simple enums is deprecated. Use `#[pyclass(eq, eq_int)` to keep the current behavior. - --> tests/ui/deprecations.rs:197:1 - | -197 | #[pyclass] - | ^^^^^^^^^^ - | - = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: use of deprecated struct `pyo3::PyCell`: `PyCell` was merged into `Bound`, use that instead; see the migration guide for more info - --> tests/ui/deprecations.rs:23:30 - | -23 | fn method_gil_ref(_slf: &PyCell) {} - | ^^^^^^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor - --> tests/ui/deprecations.rs:42:44 - | -42 | fn __eq__(&self, #[pyo3(from_py_with = "extract_gil_ref")] _other: i32) -> bool { - | ^^^^^^^^^^^^^^^^^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:18:33 - | -18 | fn cls_method_gil_ref(_cls: &PyType) {} - | ^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:23:29 - | -23 | fn method_gil_ref(_slf: &PyCell) {} - | ^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:28:36 - | -28 | fn static_method_gil_ref(_any: &PyAny) {} - | ^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor - --> tests/ui/deprecations.rs:31:53 + --> tests/ui/deprecations.rs:34:4 | -31 | fn set_foo_gil_ref(&self, #[pyo3(from_py_with = "extract_gil_ref")] _value: i32) {} - | ^^^^^^^^^^^^^^^^^ +34 | fn pyfunction_option_4( + | ^^^^^^^^^^^^^^^^^^^ -error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:37:39 - | -37 | fn set_bar_gil_ref(&self, _value: &PyAny) {} - | ^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:61:44 - | -61 | fn pyfunction_with_module_gil_ref(_module: &PyModule) -> PyResult<&str> { - | ^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:71:19 +error: use of deprecated constant `SimpleEnumWithoutEq::__pyo3__generated____richcmp__::DEPRECATION`: Implicit equality for simple enums is deprecated. Use `#[pyclass(eq, eq_int)` to keep the current behavior. + --> tests/ui/deprecations.rs:41:1 | -71 | fn module_gil_ref(_m: &PyModule) -> PyResult<()> { - | ^^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:76:57 +41 | #[pyclass] + | ^^^^^^^^^^ | -76 | fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, _m: &PyModule) -> PyResult<()> { - | ^^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor - --> tests/ui/deprecations.rs:112:27 - | -112 | #[pyo3(from_py_with = "extract_gil_ref")] _gil_ref: i32, - | ^^^^^^^^^^^^^^^^^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::function_arg`: use `&Bound<'_, T>` instead for this function argument - --> tests/ui/deprecations.rs:118:29 - | -118 | fn pyfunction_gil_ref(_any: &PyAny) {} - | ^ - -error: use of deprecated method `pyo3::deprecations::OptionGilRefs::>::function_arg`: use `Option<&Bound<'_, T>>` instead for this function argument - --> tests/ui/deprecations.rs:122:36 - | -122 | fn pyfunction_option_gil_ref(_any: Option<&PyAny>) {} - | ^^^^^^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor - --> tests/ui/deprecations.rs:147:27 - | -147 | #[pyo3(from_py_with = "PyAny::len", item("my_object"))] - | ^^^^^^^^^^^^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor - --> tests/ui/deprecations.rs:157:27 - | -157 | #[pyo3(from_py_with = "PyAny::len")] usize, - | ^^^^^^^^^^^^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor - --> tests/ui/deprecations.rs:163:31 - | -163 | Zip(#[pyo3(from_py_with = "extract_gil_ref")] i32), - | ^^^^^^^^^^^^^^^^^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor - --> tests/ui/deprecations.rs:170:27 - | -170 | #[pyo3(from_py_with = "extract_gil_ref")] - | ^^^^^^^^^^^^^^^^^ - -error: use of deprecated method `pyo3::deprecations::GilRefs::>::is_python`: use `wrap_pyfunction_bound!` instead - --> tests/ui/deprecations.rs:183:13 - | -183 | let _ = wrap_pyfunction!(double, py); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the macro `wrap_pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info)