@@ -12,7 +12,7 @@ use crate::attributes::kw::frozen;
1212use crate :: attributes:: {
1313 self , kw, take_pyo3_options, CrateAttribute , ExtendsAttribute , FreelistAttribute ,
1414 ModuleAttribute , NameAttribute , NameLitStr , NewImplTypeAttribute , NewImplTypeAttributeValue ,
15- RenameAllAttribute , StrFormatterAttribute ,
15+ RenameAllAttribute , StrFormatterAttribute , GetListAttribute
1616} ;
1717use crate :: combine_errors:: CombineErrors ;
1818#[ cfg( feature = "experimental-inspect" ) ]
@@ -97,6 +97,7 @@ pub struct PyClassPyO3Options {
9797 pub generic : Option < kw:: generic > ,
9898 pub from_py_object : Option < kw:: from_py_object > ,
9999 pub skip_from_py_object : Option < kw:: skip_from_py_object > ,
100+ pub get : Option < GetListAttribute >
100101}
101102
102103pub enum PyClassPyO3Option {
@@ -125,6 +126,7 @@ pub enum PyClassPyO3Option {
125126 Generic ( kw:: generic ) ,
126127 FromPyObject ( kw:: from_py_object ) ,
127128 SkipFromPyObject ( kw:: skip_from_py_object ) ,
129+ Get ( GetListAttribute )
128130}
129131
130132impl Parse for PyClassPyO3Option {
@@ -180,6 +182,8 @@ impl Parse for PyClassPyO3Option {
180182 input. parse ( ) . map ( PyClassPyO3Option :: FromPyObject )
181183 } else if lookahead. peek ( attributes:: kw:: skip_from_py_object) {
182184 input. parse ( ) . map ( PyClassPyO3Option :: SkipFromPyObject )
185+ } else if lookahead. peek ( attributes:: kw:: get) {
186+ input. parse ( ) . map ( PyClassPyO3Option :: Get )
183187 } else {
184188 Err ( lookahead. error ( ) )
185189 }
@@ -274,6 +278,7 @@ impl PyClassPyO3Options {
274278 ) ;
275279 set_option ! ( from_py_object)
276280 }
281+ PyClassPyO3Option :: Get ( get) => set_option ! ( get)
277282 }
278283 Ok ( ( ) )
279284 }
@@ -359,6 +364,24 @@ pub fn build_py_class(
359364 }
360365 }
361366
367+ if let Some ( get_list_attr) = & args. options . get {
368+ // get_list_attr contains the list of desired field names (NameAttribute or Ident)
369+ for name in get_list_attr. fields . iter ( ) {
370+ // find matching field in `field_options`:
371+ if let Some ( ( _, field_opts) ) =
372+ field_options. iter_mut ( ) . find ( |( f, _) | match & f. ident {
373+ Some ( ident) => ident == name,
374+ None => false ,
375+ } ) {
376+ if let Some ( old_get) = field_opts. get . replace ( Annotated :: Struct ( kw:: get_all:: default ( ) ) ) {
377+ return Err ( syn:: Error :: new ( old_get. span ( ) , "duplicate get specified" ) ) ;
378+ }
379+ } else {
380+ return Err ( syn:: Error :: new_spanned ( get_list_attr. clone ( ) , format ! ( "no field named `{}`" , name) ) ) ;
381+ }
382+ }
383+ }
384+
362385 impl_class ( & class. ident , & args, doc, field_options, methods_type, ctx)
363386}
364387
0 commit comments