@@ -31,15 +31,14 @@ use std::path::Path;
31
31
use itertools:: Itertools ;
32
32
use log:: debug;
33
33
use ruff_python_ast:: {
34
- self as ast, all:: DunderAllName , Comprehension , ElifElseClause , ExceptHandler , Expr ,
35
- ExprContext , FStringElement , Keyword , MatchCase , Parameter , ParameterWithDefault , Parameters ,
36
- Pattern , Stmt , Suite , UnaryOp ,
34
+ self as ast, Comprehension , ElifElseClause , ExceptHandler , Expr , ExprContext , FStringElement ,
35
+ Keyword , MatchCase , Parameter , ParameterWithDefault , Parameters , Pattern , Stmt , Suite , UnaryOp ,
37
36
} ;
38
37
use ruff_text_size:: { Ranged , TextRange , TextSize } ;
39
38
40
39
use ruff_diagnostics:: { Diagnostic , IsolationLevel } ;
41
40
use ruff_notebook:: { CellOffsets , NotebookIndex } ;
42
- use ruff_python_ast:: all:: { extract_all_names, DunderAllFlags } ;
41
+ use ruff_python_ast:: all:: { extract_all_names, DunderAllFlags , DunderAllNames } ;
43
42
use ruff_python_ast:: helpers:: {
44
43
collect_import_from_member, extract_handled_exceptions, is_docstring_stmt, to_module_path,
45
44
} ;
@@ -2109,45 +2108,55 @@ impl<'a> Checker<'a> {
2109
2108
fn visit_exports ( & mut self ) {
2110
2109
let snapshot = self . semantic . snapshot ( ) ;
2111
2110
2112
- let exports : Vec < DunderAllName > = self
2111
+ let definitions : Vec < DunderAllNames > = self
2113
2112
. semantic
2114
2113
. global_scope ( )
2115
2114
. get_all ( "__all__" )
2116
2115
. map ( |binding_id| & self . semantic . bindings [ binding_id] )
2117
2116
. filter_map ( |binding| match & binding. kind {
2118
- BindingKind :: Export ( Export { names } ) => Some ( names. iter ( ) . copied ( ) ) ,
2117
+ BindingKind :: Export ( Export { names } ) => Some ( DunderAllNames :: new (
2118
+ binding. range ( ) ,
2119
+ names. iter ( ) . copied ( ) . collect ( ) ,
2120
+ ) ) ,
2119
2121
_ => None ,
2120
2122
} )
2121
- . flatten ( )
2122
2123
. collect ( ) ;
2123
2124
2124
- for export in exports {
2125
- let ( name, range) = ( export. name ( ) , export. range ( ) ) ;
2126
- if let Some ( binding_id) = self . semantic . global_scope ( ) . get ( name) {
2127
- self . semantic . flags |= SemanticModelFlags :: DUNDER_ALL_DEFINITION ;
2128
- // Mark anything referenced in `__all__` as used.
2129
- self . semantic
2130
- . add_global_reference ( binding_id, ExprContext :: Load , range) ;
2131
- self . semantic . flags -= SemanticModelFlags :: DUNDER_ALL_DEFINITION ;
2132
- } else {
2133
- if self . semantic . global_scope ( ) . uses_star_imports ( ) {
2134
- if self . enabled ( Rule :: UndefinedLocalWithImportStarUsage ) {
2135
- self . diagnostics . push ( Diagnostic :: new (
2136
- pyflakes:: rules:: UndefinedLocalWithImportStarUsage {
2137
- name : name. to_string ( ) ,
2138
- } ,
2139
- range,
2140
- ) ) ;
2141
- }
2125
+ for definition in definitions {
2126
+ for export in definition. names ( ) {
2127
+ let ( name, range) = ( export. name ( ) , export. range ( ) ) ;
2128
+ if let Some ( binding_id) = self . semantic . global_scope ( ) . get ( name) {
2129
+ self . semantic . flags |= SemanticModelFlags :: DUNDER_ALL_DEFINITION ;
2130
+ // Mark anything referenced in `__all__` as used.
2131
+ self . semantic
2132
+ . add_global_reference ( binding_id, ExprContext :: Load , range) ;
2133
+ self . semantic . flags -= SemanticModelFlags :: DUNDER_ALL_DEFINITION ;
2142
2134
} else {
2143
- if self . enabled ( Rule :: UndefinedExport ) {
2144
- if !self . path . ends_with ( "__init__.py" ) {
2145
- self . diagnostics . push ( Diagnostic :: new (
2146
- pyflakes:: rules:: UndefinedExport {
2147
- name : name. to_string ( ) ,
2148
- } ,
2149
- range,
2150
- ) ) ;
2135
+ if self . semantic . global_scope ( ) . uses_star_imports ( ) {
2136
+ if self . enabled ( Rule :: UndefinedLocalWithImportStarUsage ) {
2137
+ self . diagnostics . push (
2138
+ Diagnostic :: new (
2139
+ pyflakes:: rules:: UndefinedLocalWithImportStarUsage {
2140
+ name : name. to_string ( ) ,
2141
+ } ,
2142
+ range,
2143
+ )
2144
+ . with_parent ( definition. start ( ) ) ,
2145
+ ) ;
2146
+ }
2147
+ } else {
2148
+ if self . enabled ( Rule :: UndefinedExport ) {
2149
+ if !self . path . ends_with ( "__init__.py" ) {
2150
+ self . diagnostics . push (
2151
+ Diagnostic :: new (
2152
+ pyflakes:: rules:: UndefinedExport {
2153
+ name : name. to_string ( ) ,
2154
+ } ,
2155
+ range,
2156
+ )
2157
+ . with_parent ( definition. start ( ) ) ,
2158
+ ) ;
2159
+ }
2151
2160
}
2152
2161
}
2153
2162
}
0 commit comments