Skip to content

Commit

Permalink
compile error when deprecated in #[classattr] or __traverse__
Browse files Browse the repository at this point in the history
  • Loading branch information
FlickerSoul committed Jul 20, 2024
1 parent 3566c19 commit 1f605b9
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
6 changes: 4 additions & 2 deletions pyo3-macros-backend/src/pyfunction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
method::{self, CallingConvention, FnArg},
pymethod::check_generic,
};
use proc_macro2::TokenStream;
use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote, ToTokens};
use syn::{ext::IdentExt, spanned::Spanned, LitCStr, Path, Result, Token};
use syn::{
Expand Down Expand Up @@ -90,6 +90,7 @@ type DeprecatedFunctionCategoryAttribute = KeywordAttribute<attributes::kw::cate
pub struct PyFunctionDeprecatedAttribute {
pub message: DeprecatedFunctionMessageAttribute,
pub category: Option<DeprecatedFunctionCategoryAttribute>,
pub span: Span,
}

pub trait WarningFactory {
Expand Down Expand Up @@ -124,7 +125,7 @@ impl Parse for PyFunctionDeprecatedAttribute {
let mut message: Option<DeprecatedFunctionMessageAttribute> = None;
let mut category: Option<DeprecatedFunctionCategoryAttribute> = None;

input.parse::<attributes::kw::deprecated>()?;
let span = input.parse::<attributes::kw::deprecated>()?.span();

let content;
syn::parenthesized!(content in input);
Expand Down Expand Up @@ -155,6 +156,7 @@ impl Parse for PyFunctionDeprecatedAttribute {
"missing `message` in `deprecated` attribute",
))?,
category,
span,
})
}
}
Expand Down
10 changes: 10 additions & 0 deletions pyo3-macros-backend/src/pymethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,11 @@ fn impl_traverse_slot(
}
}

ensure_spanned!(
spec.deprecated.as_ref().is_none(),
spec.deprecated.as_ref().unwrap().span => "__traverse__ cannot be used with #[pyo3(deprecated)]"
);

let rust_fn_ident = spec.name;

let associated_method = quote! {
Expand Down Expand Up @@ -490,6 +495,11 @@ fn impl_py_class_attribute(
args[0].ty().span() => "#[classattr] can only have one argument (of type pyo3::Python)"
);

ensure_spanned!(
spec.deprecated.as_ref().is_none(),
spec.deprecated.as_ref().unwrap().span => "#[classattr] cannot be used with #[pyo3(deprecated)]"
);

let name = &spec.name;
let fncall = if py_arg.is_some() {
quote!(function(py))
Expand Down
20 changes: 20 additions & 0 deletions tests/ui/invalid_deprecated_pyfunction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,24 @@ fn random_key_deprecated() {}
#[pyo3(deprecated(message = "non CStr string"))]
fn non_cstr_string_deprecated() {}

#[pyclass]
struct DeprecatedMethodContainer {}

#[pymethods]
impl DeprecatedMethodContainer {
#[classattr]
#[pyo3(deprecated(message = c"deprecated class attr"))]
fn deprecated_class_attr() -> i32 {
5
}
}

#[pymethods]
impl DeprecatedMethodContainer {
#[pyo3(deprecated(message = c"deprecated __traverse__"))]
fn __traverse__(&self, _visit: pyo3::gc::PyVisit<'_>) -> Result<(), pyo3::PyTraverseError> {
Ok(())
}
}

fn main() {}
12 changes: 12 additions & 0 deletions tests/ui/invalid_deprecated_pyfunction.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,15 @@ error: expected C string literal
|
28 | #[pyo3(deprecated(message = "non CStr string"))]
| ^^^^^^^^^^^^^^^^^

error: #[classattr] cannot be used with #[pyo3(deprecated)]
--> tests/ui/invalid_deprecated_pyfunction.rs:37:12
|
37 | #[pyo3(deprecated(message = c"deprecated class attr"))]
| ^^^^^^^^^^

error: __traverse__ cannot be used with #[pyo3(deprecated)]
--> tests/ui/invalid_deprecated_pyfunction.rs:45:12
|
45 | #[pyo3(deprecated(message = c"deprecated __traverse__"))]
| ^^^^^^^^^^

0 comments on commit 1f605b9

Please sign in to comment.