From 1cfba4d4cc88bc861de53f0c3c645f5c9eb7198d Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Wed, 6 Mar 2024 23:34:53 +0100 Subject: [PATCH] deprecate `&PyModule` as `#[pymodule]` argument type --- pyo3-macros-backend/src/module.rs | 25 ++++++++++++++++++-- src/impl_/pymethods.rs | 39 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/pyo3-macros-backend/src/module.rs b/pyo3-macros-backend/src/module.rs index 7173fa8647d..54367138783 100644 --- a/pyo3-macros-backend/src/module.rs +++ b/pyo3-macros-backend/src/module.rs @@ -7,7 +7,7 @@ use crate::{ pyfunction::{impl_wrap_pyfunction, PyFunctionOptions}, }; use proc_macro2::TokenStream; -use quote::quote; +use quote::{quote, quote_spanned}; use syn::{ ext::IdentExt, parse::{Parse, ParseStream}, @@ -295,8 +295,29 @@ pub fn pymodule_function_impl(mut function: syn::ItemFn) -> Result } module_args.push(quote!(::std::convert::Into::into(BoundRef(module)))); + let syn::ItemFn { + attrs, sig, block, .. + } = &function; + + let extractors = 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 = &pat_ident.ident; + return Some(quote_spanned! { pat_type.span() => { + let (_, e) = #pyo3_path::impl_::pymethods::inspect_type(#ident); + let _ = e.extract_gil_ref(); + }}); + } + } + None + }); + Ok(quote! { - #function + #(#attrs)* + #vis #sig { + #(#extractors)* + #block + } #vis mod #ident { #initialization } diff --git a/src/impl_/pymethods.rs b/src/impl_/pymethods.rs index df89dba7dbd..c63f3e88055 100644 --- a/src/impl_/pymethods.rs +++ b/src/impl_/pymethods.rs @@ -580,3 +580,42 @@ pub unsafe fn tp_new_impl( .create_class_object_of_type(py, target_type) .map(Bound::into_ptr) } + +pub fn inspect_type(t: T) -> (T, Extractor) { + (t, Extractor::new()) +} + +pub struct Extractor(NotAGilRef); +pub struct NotAGilRef(std::marker::PhantomData); + +pub trait IsGilRef {} + +impl IsGilRef for &'_ T {} + +impl Extractor { + pub fn new() -> Self { + Extractor(NotAGilRef(std::marker::PhantomData)) + } +} + +impl Extractor { + #[cfg_attr( + not(feature = "gil-refs"), + deprecated( + since = "0.21.0", + note = "use `&Bound<'_, T>` instead for this function argument" + ) + )] + pub fn extract_gil_ref(&self) {} +} + +impl NotAGilRef { + pub fn extract_gil_ref(&self) {} +} + +impl std::ops::Deref for Extractor { + type Target = NotAGilRef; + fn deref(&self) -> &Self::Target { + &self.0 + } +}