@@ -12,6 +12,7 @@ use crate::attributes::kw::frozen;
1212use crate :: attributes:: {
1313 self , kw, take_pyo3_options, CrateAttribute , ExtendsAttribute , FreelistAttribute ,
1414 ModuleAttribute , NameAttribute , NameLitStr , RenameAllAttribute , StrFormatterAttribute ,
15+ GetListAttribute
1516} ;
1617use crate :: combine_errors:: CombineErrors ;
1718#[ cfg( feature = "experimental-inspect" ) ]
@@ -95,6 +96,7 @@ pub struct PyClassPyO3Options {
9596 pub generic : Option < kw:: generic > ,
9697 pub from_py_object : Option < kw:: from_py_object > ,
9798 pub skip_from_py_object : Option < kw:: skip_from_py_object > ,
99+ pub get : Option < GetListAttribute >
98100}
99101
100102pub enum PyClassPyO3Option {
@@ -122,6 +124,7 @@ pub enum PyClassPyO3Option {
122124 Generic ( kw:: generic ) ,
123125 FromPyObject ( kw:: from_py_object ) ,
124126 SkipFromPyObject ( kw:: skip_from_py_object ) ,
127+ Get ( GetListAttribute )
125128}
126129
127130impl Parse for PyClassPyO3Option {
@@ -175,6 +178,8 @@ impl Parse for PyClassPyO3Option {
175178 input. parse ( ) . map ( PyClassPyO3Option :: FromPyObject )
176179 } else if lookahead. peek ( attributes:: kw:: skip_from_py_object) {
177180 input. parse ( ) . map ( PyClassPyO3Option :: SkipFromPyObject )
181+ } else if lookahead. peek ( attributes:: kw:: get) {
182+ input. parse ( ) . map ( PyClassPyO3Option :: Get )
178183 } else {
179184 Err ( lookahead. error ( ) )
180185 }
@@ -268,6 +273,7 @@ impl PyClassPyO3Options {
268273 ) ;
269274 set_option ! ( from_py_object)
270275 }
276+ PyClassPyO3Option :: Get ( get) => set_option ! ( get)
271277 }
272278 Ok ( ( ) )
273279 }
@@ -353,6 +359,25 @@ pub fn build_py_class(
353359 }
354360 }
355361
362+ if let Some ( get_list_attr) = & args. options . get {
363+ // get_list_attr contains the list of desired field names (NameAttribute or Ident)
364+ for name in get_list_attr. fields . iter ( ) {
365+ // find matching field in `field_options`:
366+ if let Some ( ( _, field_opts) ) =
367+ field_options. iter_mut ( ) . find ( |( f, _) | match & f. ident {
368+ Some ( ident) => ident == name,
369+ None => false ,
370+ } ) {
371+ if let Some ( old_get) = field_opts. get . replace ( Annotated :: Struct ( kw:: get_all:: default ( ) ) ) {
372+ return Err ( syn:: Error :: new ( old_get. span ( ) , "duplicate get specified" ) ) ;
373+ }
374+ } else {
375+ return Err ( syn:: Error :: new_spanned ( get_list_attr. clone ( ) , format ! ( "no field named `{}`" , name) ) ) ;
376+ }
377+ }
378+ }
379+
380+
356381 impl_class ( & class. ident , & args, doc, field_options, methods_type, ctx)
357382}
358383
0 commit comments