@@ -29,8 +29,9 @@ use ruff_python_ast::{
2929 InterpolatedStringElements , Keyword , MatchCase , ModExpression , ModModule , Operator , Parameters ,
3030 Pattern , PatternMatchAs , PatternMatchClass , PatternMatchMapping , PatternMatchOr ,
3131 PatternMatchSequence , PatternMatchSingleton , PatternMatchStar , PatternMatchValue , Singleton ,
32- Stmt , StmtAnnAssign , StmtExpr , TString , TypeParam , TypeParamParamSpec , TypeParamTypeVar ,
33- TypeParamTypeVarTuple , TypeParams , UnaryOp , WithItem ,
32+ Stmt , StmtAnnAssign , StmtExpr , StmtFor , StmtIf , StmtMatch , StmtTry , StmtWhile , StmtWith ,
33+ TString , TypeParam , TypeParamParamSpec , TypeParamTypeVar , TypeParamTypeVarTuple , TypeParams ,
34+ UnaryOp , WithItem ,
3435 visitor:: { Visitor , walk_expr} ,
3536} ;
3637use ruff_text_size:: { Ranged , TextRange } ;
@@ -3630,23 +3631,69 @@ impl Compiler {
36303631 Ok ( true )
36313632 }
36323633
3633- /// Collect simple (non-conditional) annotations from module body
3634+ /// Collect simple annotations from module body in AST order (including nested blocks)
36343635 /// Returns list of (name, annotation_expr) pairs
3636+ /// This must match the order that annotations are compiled to ensure
3637+ /// conditional_annotation_index stays in sync with __annotate__ enumeration.
36353638 fn collect_simple_annotations ( body : & [ Stmt ] ) -> Vec < ( & str , & Expr ) > {
3636- let mut annotations = Vec :: new ( ) ;
3637- for stmt in body {
3638- if let Stmt :: AnnAssign ( StmtAnnAssign {
3639- target,
3640- annotation,
3641- simple,
3642- ..
3643- } ) = stmt
3644- && * simple
3645- && let Expr :: Name ( ExprName { id, .. } ) = target. as_ref ( )
3646- {
3647- annotations. push ( ( id. as_str ( ) , annotation. as_ref ( ) ) ) ;
3639+ fn walk < ' a > ( stmts : & ' a [ Stmt ] , out : & mut Vec < ( & ' a str , & ' a Expr ) > ) {
3640+ for stmt in stmts {
3641+ match stmt {
3642+ Stmt :: AnnAssign ( StmtAnnAssign {
3643+ target,
3644+ annotation,
3645+ simple,
3646+ ..
3647+ } ) if * simple && matches ! ( target. as_ref( ) , Expr :: Name ( _) ) => {
3648+ if let Expr :: Name ( ExprName { id, .. } ) = target. as_ref ( ) {
3649+ out. push ( ( id. as_str ( ) , annotation. as_ref ( ) ) ) ;
3650+ }
3651+ }
3652+ Stmt :: If ( StmtIf {
3653+ body,
3654+ elif_else_clauses,
3655+ ..
3656+ } ) => {
3657+ walk ( body, out) ;
3658+ for clause in elif_else_clauses {
3659+ walk ( & clause. body , out) ;
3660+ }
3661+ }
3662+ Stmt :: For ( StmtFor { body, orelse, .. } )
3663+ | Stmt :: While ( StmtWhile { body, orelse, .. } ) => {
3664+ walk ( body, out) ;
3665+ walk ( orelse, out) ;
3666+ }
3667+ Stmt :: With ( StmtWith { body, .. } ) => walk ( body, out) ,
3668+ Stmt :: Try ( StmtTry {
3669+ body,
3670+ handlers,
3671+ orelse,
3672+ finalbody,
3673+ ..
3674+ } ) => {
3675+ walk ( body, out) ;
3676+ for handler in handlers {
3677+ let ExceptHandler :: ExceptHandler ( ExceptHandlerExceptHandler {
3678+ body,
3679+ ..
3680+ } ) = handler;
3681+ walk ( body, out) ;
3682+ }
3683+ walk ( orelse, out) ;
3684+ walk ( finalbody, out) ;
3685+ }
3686+ Stmt :: Match ( StmtMatch { cases, .. } ) => {
3687+ for case in cases {
3688+ walk ( & case. body , out) ;
3689+ }
3690+ }
3691+ _ => { }
3692+ }
36483693 }
36493694 }
3695+ let mut annotations = Vec :: new ( ) ;
3696+ walk ( body, & mut annotations) ;
36503697 annotations
36513698 }
36523699
0 commit comments