@@ -43,14 +43,9 @@ pub fn module_introspection_code<'a>(
4343 members
4444 . into_iter ( )
4545 . zip ( members_cfg_attrs)
46- . filter_map ( |( member, attributes) | {
47- if attributes. is_empty ( ) {
48- Some ( IntrospectionNode :: IntrospectionId ( Some ( ident_to_type (
49- member,
50- ) ) ) )
51- } else {
52- None // TODO: properly interpret cfg attributes
53- }
46+ . map ( |( member, attributes) | AttributedIntrospectionNode {
47+ node : IntrospectionNode :: IntrospectionId ( Some ( ident_to_type ( member) ) ) ,
48+ attributes,
5449 } )
5550 . collect ( ) ,
5651 ) ,
@@ -138,7 +133,7 @@ pub fn function_introspection_code(
138133 }
139134 let decorators = decorators
140135 . into_iter ( )
141- . map ( |d| IntrospectionNode :: String ( d. into ( ) ) )
136+ . map ( |d| IntrospectionNode :: String ( d. into ( ) ) . into ( ) )
142137 . collect :: < Vec < _ > > ( ) ;
143138 if !decorators. is_empty ( ) {
144139 desc. insert ( "decorators" , IntrospectionNode :: List ( decorators) ) ;
@@ -220,9 +215,12 @@ fn arguments_introspection_data<'a>(
220215 let mut kwarg = None ;
221216
222217 if let Some ( first_argument) = first_argument {
223- posonlyargs. push ( IntrospectionNode :: Map (
224- [ ( "name" , IntrospectionNode :: String ( first_argument. into ( ) ) ) ] . into ( ) ,
225- ) ) ;
218+ posonlyargs. push (
219+ IntrospectionNode :: Map (
220+ [ ( "name" , IntrospectionNode :: String ( first_argument. into ( ) ) ) ] . into ( ) ,
221+ )
222+ . into ( ) ,
223+ ) ;
226224 }
227225
228226 for ( i, param) in signature
@@ -296,7 +294,7 @@ fn argument_introspection_data<'a>(
296294 name : & ' a str ,
297295 desc : & ' a RegularArg < ' _ > ,
298296 class_type : Option < & Type > ,
299- ) -> IntrospectionNode < ' a > {
297+ ) -> AttributedIntrospectionNode < ' a > {
300298 let mut params: HashMap < _ , _ > = [ ( "name" , IntrospectionNode :: String ( name. into ( ) ) ) ] . into ( ) ;
301299 if desc. default_value . is_some ( ) {
302300 params. insert (
@@ -338,7 +336,7 @@ fn argument_introspection_data<'a>(
338336 ) ;
339337 }
340338 }
341- IntrospectionNode :: Map ( params)
339+ IntrospectionNode :: Map ( params) . into ( )
342340}
343341
344342enum IntrospectionNode < ' a > {
@@ -348,7 +346,7 @@ enum IntrospectionNode<'a> {
348346 InputType { rust_type : Type , nullable : bool } ,
349347 OutputType { rust_type : Type , is_final : bool } ,
350348 Map ( HashMap < & ' static str , IntrospectionNode < ' a > > ) ,
351- List ( Vec < IntrospectionNode < ' a > > ) ,
349+ List ( Vec < AttributedIntrospectionNode < ' a > > ) ,
352350}
353351
354352impl IntrospectionNode < ' _ > {
@@ -381,9 +379,9 @@ impl IntrospectionNode<'_> {
381379 Self :: IntrospectionId ( ident) => {
382380 content. push_str ( "\" " ) ;
383381 content. push_tokens ( if let Some ( ident) = ident {
384- quote ! { #ident:: _PYO3_INTROSPECTION_ID }
382+ quote ! { #ident:: _PYO3_INTROSPECTION_ID. as_bytes ( ) }
385383 } else {
386- quote ! { _PYO3_INTROSPECTION_ID }
384+ quote ! { _PYO3_INTROSPECTION_ID. as_bytes ( ) }
387385 } ) ;
388386 content. push_str ( "\" " ) ;
389387 }
@@ -392,7 +390,7 @@ impl IntrospectionNode<'_> {
392390 nullable,
393391 } => {
394392 content. push_str ( "\" " ) ;
395- content. push_tokens ( quote ! { <#rust_type as #pyo3_crate_path:: impl_:: extract_argument:: PyFunctionArgument <false >>:: INPUT_TYPE } ) ;
393+ content. push_tokens ( quote ! { <#rust_type as #pyo3_crate_path:: impl_:: extract_argument:: PyFunctionArgument <false >>:: INPUT_TYPE . as_bytes ( ) } ) ;
396394 if nullable {
397395 content. push_str ( " | None" ) ;
398396 }
@@ -406,7 +404,7 @@ impl IntrospectionNode<'_> {
406404 if is_final {
407405 content. push_str ( "typing.Final[" ) ;
408406 }
409- content. push_tokens ( quote ! { <#rust_type as #pyo3_crate_path:: impl_:: introspection:: PyReturnType >:: OUTPUT_TYPE } ) ;
407+ content. push_tokens ( quote ! { <#rust_type as #pyo3_crate_path:: impl_:: introspection:: PyReturnType >:: OUTPUT_TYPE . as_bytes ( ) } ) ;
410408 if is_final {
411409 content. push_str ( "]" ) ;
412410 }
@@ -426,18 +424,45 @@ impl IntrospectionNode<'_> {
426424 }
427425 Self :: List ( list) => {
428426 content. push_str ( "[" ) ;
429- for ( i, value) in list. into_iter ( ) . enumerate ( ) {
430- if i > 0 {
431- content. push_str ( "," ) ;
427+ for ( i, AttributedIntrospectionNode { node, attributes } ) in
428+ list. into_iter ( ) . enumerate ( )
429+ {
430+ if attributes. is_empty ( ) {
431+ if i > 0 {
432+ content. push_str ( "," ) ;
433+ }
434+ node. add_to_serialization ( content, pyo3_crate_path) ;
435+ } else {
436+ // We serialize the element to easily gate it behind the attributes
437+ let mut nested_builder = ConcatenationBuilder :: default ( ) ;
438+ if i > 0 {
439+ nested_builder. push_str ( "," ) ;
440+ }
441+ node. add_to_serialization ( & mut nested_builder, pyo3_crate_path) ;
442+ let nested_content = nested_builder. into_token_stream ( pyo3_crate_path) ;
443+ content. push_tokens ( quote ! { #( #attributes) * #nested_content } ) ;
432444 }
433- value. add_to_serialization ( content, pyo3_crate_path) ;
434445 }
435446 content. push_str ( "]" ) ;
436447 }
437448 }
438449 }
439450}
440451
452+ struct AttributedIntrospectionNode < ' a > {
453+ node : IntrospectionNode < ' a > ,
454+ attributes : & ' a [ Attribute ] ,
455+ }
456+
457+ impl < ' a > From < IntrospectionNode < ' a > > for AttributedIntrospectionNode < ' a > {
458+ fn from ( node : IntrospectionNode < ' a > ) -> Self {
459+ Self {
460+ node,
461+ attributes : & [ ] ,
462+ }
463+ }
464+ }
465+
441466#[ derive( Default ) ]
442467struct ConcatenationBuilder {
443468 elements : Vec < ConcatenationBuilderElement > ,
@@ -490,7 +515,7 @@ impl ConcatenationBuilder {
490515
491516 quote ! {
492517 {
493- const PIECES : & [ & [ u8 ] ] = & [ #( #elements. as_bytes ( ) , ) * ] ;
518+ const PIECES : & [ & [ u8 ] ] = & [ #( #elements , ) * ] ;
494519 & #pyo3_crate_path:: impl_:: concat:: combine_to_array:: <{
495520 #pyo3_crate_path:: impl_:: concat:: combined_len( PIECES )
496521 } >( PIECES )
@@ -507,7 +532,7 @@ enum ConcatenationBuilderElement {
507532impl ToTokens for ConcatenationBuilderElement {
508533 fn to_tokens ( & self , tokens : & mut TokenStream ) {
509534 match self {
510- Self :: String ( s) => s . to_tokens ( tokens) ,
535+ Self :: String ( s) => quote ! { #s . as_bytes ( ) } . to_tokens ( tokens) ,
511536 Self :: TokenStream ( ts) => ts. to_tokens ( tokens) ,
512537 }
513538 }
0 commit comments