(
&mut self,
annotation: &ast::Expr,
is_ann_assign: bool,
)
| 1255 | } |
| 1256 | |
| 1257 | fn scan_annotation_inner( |
| 1258 | &mut self, |
| 1259 | annotation: &ast::Expr, |
| 1260 | is_ann_assign: bool, |
| 1261 | ) -> SymbolTableResult { |
| 1262 | let current_scope = self.tables.last().map(|t| t.typ); |
| 1263 | |
| 1264 | // PEP 649: Only AnnAssign annotations can be conditional. |
| 1265 | // Function parameter/return annotations are never conditional. |
| 1266 | if is_ann_assign && !self.future_annotations { |
| 1267 | let is_conditional = matches!(current_scope, Some(CompilerScope::Module)) |
| 1268 | || (matches!(current_scope, Some(CompilerScope::Class)) |
| 1269 | && self.in_conditional_block); |
| 1270 | |
| 1271 | if is_conditional && !self.tables.last().unwrap().has_conditional_annotations { |
| 1272 | self.tables.last_mut().unwrap().has_conditional_annotations = true; |
| 1273 | self.register_name( |
| 1274 | "__conditional_annotations__", |
| 1275 | SymbolUsage::Assigned, |
| 1276 | annotation.range(), |
| 1277 | )?; |
| 1278 | self.register_name( |
| 1279 | "__conditional_annotations__", |
| 1280 | SymbolUsage::Used, |
| 1281 | annotation.range(), |
| 1282 | )?; |
| 1283 | } |
| 1284 | } |
| 1285 | |
| 1286 | // Create annotation scope for deferred evaluation |
| 1287 | let line_number = self.line_index_start(annotation.range()); |
| 1288 | self.enter_annotation_scope(line_number); |
| 1289 | |
| 1290 | if self.future_annotations { |
| 1291 | // PEP 563: annotations are stringified at compile time |
| 1292 | // Don't scan expression - symbols would fail to resolve |
| 1293 | // Just create the annotation_block structure |
| 1294 | self.leave_annotation_scope(); |
| 1295 | return Ok(()); |
| 1296 | } |
| 1297 | |
| 1298 | // PEP 649: scan expression for symbol references |
| 1299 | // Class annotations are evaluated in class locals (not module globals) |
| 1300 | let was_in_annotation = self.in_annotation; |
| 1301 | self.in_annotation = true; |
| 1302 | let result = self.scan_expression(annotation, ExpressionContext::Load); |
| 1303 | self.in_annotation = was_in_annotation; |
| 1304 | |
| 1305 | self.leave_annotation_scope(); |
| 1306 | |
| 1307 | result |
| 1308 | } |
| 1309 | |
| 1310 | fn scan_statement(&mut self, statement: &ast::Stmt) -> SymbolTableResult { |
| 1311 | use ast::*; |
no test coverage detected