Skip to content

Commit 852a5ea

Browse files
committed
add opt-out option
1 parent 91afce0 commit 852a5ea

File tree

3 files changed

+17
-3
lines changed

3 files changed

+17
-3
lines changed

pyo3-macros-backend/src/attributes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub mod kw {
5353
syn::custom_keyword!(warn);
5454
syn::custom_keyword!(message);
5555
syn::custom_keyword!(category);
56+
syn::custom_keyword!(skip_from_py_object);
5657
}
5758

5859
fn take_int(read: &mut &str, tracker: &mut usize) -> String {

pyo3-macros-backend/src/pyclass.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ pub struct PyClassPyO3Options {
9090
pub unsendable: Option<kw::unsendable>,
9191
pub weakref: Option<kw::weakref>,
9292
pub generic: Option<kw::generic>,
93+
pub skip_from_py_object: Option<kw::skip_from_py_object>,
9394
}
9495

9596
pub enum PyClassPyO3Option {
@@ -115,6 +116,7 @@ pub enum PyClassPyO3Option {
115116
Unsendable(kw::unsendable),
116117
Weakref(kw::weakref),
117118
Generic(kw::generic),
119+
SkipFromPyObject(kw::skip_from_py_object),
118120
}
119121

120122
impl Parse for PyClassPyO3Option {
@@ -164,6 +166,8 @@ impl Parse for PyClassPyO3Option {
164166
input.parse().map(PyClassPyO3Option::Weakref)
165167
} else if lookahead.peek(attributes::kw::generic) {
166168
input.parse().map(PyClassPyO3Option::Generic)
169+
} else if lookahead.peek(attributes::kw::skip_from_py_object) {
170+
input.parse().map(PyClassPyO3Option::SkipFromPyObject)
167171
} else {
168172
Err(lookahead.error())
169173
}
@@ -243,6 +247,9 @@ impl PyClassPyO3Options {
243247
set_option!(weakref);
244248
}
245249
PyClassPyO3Option::Generic(generic) => set_option!(generic),
250+
PyClassPyO3Option::SkipFromPyObject(skip_from_py_object) => {
251+
set_option!(skip_from_py_object)
252+
}
246253
}
247254
Ok(())
248255
}
@@ -2497,8 +2504,14 @@ impl<'a> PyClassImplsBuilder<'a> {
24972504
quote! {}
24982505
};
24992506

2507+
let extract_pyclass_with_clone = if self.attr.options.skip_from_py_object.is_none() {
2508+
quote!( impl #pyo3_path::impl_::pyclass::ExtractPyClassWithClone for #cls {} )
2509+
} else {
2510+
TokenStream::new()
2511+
};
2512+
25002513
Ok(quote! {
2501-
impl #pyo3_path::impl_::pyclass::ExtractPyClassWithClone for #cls {}
2514+
#extract_pyclass_with_clone
25022515

25032516
#assertions
25042517

tests/ui/invalid_pyclass_args.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: expected one of: `crate`, `dict`, `eq`, `eq_int`, `extends`, `freelist`, `frozen`, `get_all`, `hash`, `immutable_type`, `mapping`, `module`, `name`, `ord`, `rename_all`, `sequence`, `set_all`, `str`, `subclass`, `unsendable`, `weakref`, `generic`
1+
error: expected one of: `crate`, `dict`, `eq`, `eq_int`, `extends`, `freelist`, `frozen`, `get_all`, `hash`, `immutable_type`, `mapping`, `module`, `name`, `ord`, `rename_all`, `sequence`, `set_all`, `str`, `subclass`, `unsendable`, `weakref`, `generic`, `skip_from_py_object`
22
--> tests/ui/invalid_pyclass_args.rs:4:11
33
|
44
4 | #[pyclass(extend=pyo3::types::PyDict)]
@@ -46,7 +46,7 @@ error: expected string literal
4646
25 | #[pyclass(module = my_module)]
4747
| ^^^^^^^^^
4848

49-
error: expected one of: `crate`, `dict`, `eq`, `eq_int`, `extends`, `freelist`, `frozen`, `get_all`, `hash`, `immutable_type`, `mapping`, `module`, `name`, `ord`, `rename_all`, `sequence`, `set_all`, `str`, `subclass`, `unsendable`, `weakref`, `generic`
49+
error: expected one of: `crate`, `dict`, `eq`, `eq_int`, `extends`, `freelist`, `frozen`, `get_all`, `hash`, `immutable_type`, `mapping`, `module`, `name`, `ord`, `rename_all`, `sequence`, `set_all`, `str`, `subclass`, `unsendable`, `weakref`, `generic`, `skip_from_py_object`
5050
--> tests/ui/invalid_pyclass_args.rs:28:11
5151
|
5252
28 | #[pyclass(weakrev)]

0 commit comments

Comments
 (0)