From 44310ec7e0b3b4ec3ceb50683d3b8b867eac6145 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Tue, 6 Dec 2022 22:38:32 +0100 Subject: [PATCH 1/4] Forward cfgs on pyclass fields to the method defs --- pyo3-macros-backend/src/pymethod.rs | 18 ++++++++++++++++++ src/test_hygiene/pyclass.rs | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/pyo3-macros-backend/src/pymethod.rs b/pyo3-macros-backend/src/pymethod.rs index 7feafc99..fa81c6d4 100644 --- a/pyo3-macros-backend/src/pymethod.rs +++ b/pyo3-macros-backend/src/pymethod.rs @@ -519,7 +519,15 @@ pub fn impl_py_setter_def( } }; + let mut cfg_attrs = TokenStream::new(); + if let PropertyType::Descriptor { field, .. } = &property_type { + for attr in field.attrs.iter().filter(|attr| attr.path.is_ident("cfg")) { + attr.to_tokens(&mut cfg_attrs); + } + } + let associated_method = quote! { + #cfg_attrs unsafe fn #wrapper_ident( _py: _pyo3::Python<'_>, _slf: *mut _pyo3::ffi::PyObject, @@ -538,6 +546,7 @@ pub fn impl_py_setter_def( }; let method_def = quote! { + #cfg_attrs _pyo3::class::PyMethodDefType::Setter({ #deprecations _pyo3::class::PySetterDef::new( @@ -653,7 +662,15 @@ pub fn impl_py_getter_def( } }; + let mut cfg_attrs = TokenStream::new(); + if let PropertyType::Descriptor { field, .. } = &property_type { + for attr in field.attrs.iter().filter(|attr| attr.path.is_ident("cfg")) { + attr.to_tokens(&mut cfg_attrs); + } + } + let associated_method = quote! { + #cfg_attrs unsafe fn #wrapper_ident( _py: _pyo3::Python<'_>, _slf: *mut _pyo3::ffi::PyObject @@ -665,6 +682,7 @@ pub fn impl_py_getter_def( }; let method_def = quote! { + #cfg_attrs _pyo3::class::PyMethodDefType::Getter({ #deprecations _pyo3::class::PyGetterDef::new( diff --git a/src/test_hygiene/pyclass.rs b/src/test_hygiene/pyclass.rs index d86ea09c..0b535abe 100644 --- a/src/test_hygiene/pyclass.rs +++ b/src/test_hygiene/pyclass.rs @@ -34,3 +34,28 @@ pub struct Bar { pub enum Enum { Var0, } + +#[crate::pyclass] +#[pyo3(crate = "crate")] +pub struct Foo3 { + #[pyo3(get, set)] + #[cfg(FALSE)] + field: i32, + + #[pyo3(get, set)] + #[cfg(not(FALSE))] + field: u32, +} + +#[crate::pyclass] +#[pyo3(crate = "crate")] +pub struct Foo4 { + #[pyo3(get, set)] + #[cfg(FALSE)] + #[cfg(not(FALSE))] + field: i32, + + #[pyo3(get, set)] + #[cfg(any(not(FALSE)))] + field: u32, +} From 5198722dd984eff325a6d03ace06fc4744b33752 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Wed, 28 Dec 2022 23:11:39 +0100 Subject: [PATCH 2/4] Add test --- tests/test_field_cfg.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/test_field_cfg.rs diff --git a/tests/test_field_cfg.rs b/tests/test_field_cfg.rs new file mode 100644 index 00000000..dc84701c --- /dev/null +++ b/tests/test_field_cfg.rs @@ -0,0 +1,24 @@ +#![cfg(feature = "macros")] + +use pyo3::prelude::*; + +#[pyclass] +struct CfgClass { + #[pyo3(get, set)] + #[cfg(any())] + pub a: u32, + #[pyo3(get, set)] + #[cfg(all())] + pub b: u32, +} + +#[test] +fn test_cfg() { + Python::with_gil(|py| { + let cfg = CfgClass { b: 3 }; + let py_cfg = Py::new(py, cfg).unwrap(); + assert!(py_cfg.as_ref(py).getattr("a").is_err()); + let b: u32 = py_cfg.as_ref(py).getattr("b").unwrap().extract().unwrap(); + assert_eq!(b, 3); + }); +} From 8f51142013cf9f34c6652fc5f10af1fa4d5473c1 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Wed, 28 Dec 2022 23:13:55 +0100 Subject: [PATCH 3/4] Add changelog --- newsfragments/2796.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/2796.md diff --git a/newsfragments/2796.md b/newsfragments/2796.md new file mode 100644 index 00000000..6d50956d --- /dev/null +++ b/newsfragments/2796.md @@ -0,0 +1 @@ +Mixing cfgs and pyo3 attributes on struct fields will now work \ No newline at end of file From 530c5b319306865e91320df5909de1bb111d1356 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Thu, 29 Dec 2022 15:13:38 +0100 Subject: [PATCH 4/4] Fix changelog --- newsfragments/{2796.md => 2796.changed.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename newsfragments/{2796.md => 2796.changed.md} (100%) diff --git a/newsfragments/2796.md b/newsfragments/2796.changed.md similarity index 100% rename from newsfragments/2796.md rename to newsfragments/2796.changed.md