|
14 | 14 | from collections import defaultdict |
15 | 15 | from enum import Enum |
16 | 16 | from functools import cached_property |
17 | | -from typing import TYPE_CHECKING, NamedTuple |
| 17 | +from typing import TYPE_CHECKING |
18 | 18 |
|
19 | 19 | import astroid |
20 | 20 | import astroid.exceptions |
|
33 | 33 |
|
34 | 34 | if TYPE_CHECKING: |
35 | 35 | from collections.abc import Generator, Iterable, Iterator |
36 | | - from typing import Any |
37 | 36 |
|
38 | 37 | from astroid.nodes import _base_nodes |
39 | 38 | from astroid.typing import InferenceResult |
@@ -475,72 +474,49 @@ def _has_locals_call_after_node(stmt: nodes.NodeNG, scope: nodes.FunctionDef) -> |
475 | 474 | } |
476 | 475 |
|
477 | 476 |
|
478 | | -class ScopeConsumer(NamedTuple): |
479 | | - """Store nodes and their consumption states.""" |
| 477 | +class NamesConsumer: |
| 478 | + """A simple class to handle consumed, to consume and scope type info of node locals.""" |
| 479 | + |
| 480 | + node: nodes.NodeNG |
| 481 | + scope_type: str |
480 | 482 |
|
481 | 483 | to_consume: Consumption |
482 | 484 | consumed: Consumption |
483 | 485 | consumed_uncertain: Consumption |
484 | | - scope_type: str |
| 486 | + """Retrieves nodes filtered out by get_next_to_consume() that may not |
| 487 | + have executed. |
485 | 488 |
|
| 489 | + These include nodes such as statements in except blocks, or statements |
| 490 | + in try blocks (when evaluating their corresponding except and finally |
| 491 | + blocks). Checkers that want to treat the statements as executed |
| 492 | + (e.g. for unused-variable) may need to add them back. |
| 493 | + """ |
486 | 494 |
|
487 | | -class NamesConsumer: |
488 | | - """A simple class to handle consumed, to consume and scope type info of node locals.""" |
489 | | - |
490 | | - def __init__(self, node: nodes.NodeNG, scope_type: str) -> None: |
491 | | - self._atomic = ScopeConsumer( |
492 | | - copy.copy(node.locals), |
493 | | - {}, |
494 | | - defaultdict(list), |
495 | | - scope_type, |
496 | | - ) |
| 495 | + def __init__(self, node: nodes.NodeNG, scope_type: str): |
497 | 496 | self.node = node |
| 497 | + self.scope_type = scope_type |
| 498 | + |
| 499 | + self.to_consume = copy.copy(node.locals) |
| 500 | + self.consumed = {} |
| 501 | + self.consumed_uncertain = defaultdict(list) |
| 502 | + |
498 | 503 | self.names_under_always_false_test: set[str] = set() |
499 | 504 | self.names_defined_under_one_branch_only: set[str] = set() |
500 | 505 |
|
501 | 506 | def __repr__(self) -> str: |
502 | | - _to_consumes = [f"{k}->{v}" for k, v in self._atomic.to_consume.items()] |
503 | | - _consumed = [f"{k}->{v}" for k, v in self._atomic.consumed.items()] |
504 | | - _consumed_uncertain = [ |
505 | | - f"{k}->{v}" for k, v in self._atomic.consumed_uncertain.items() |
506 | | - ] |
| 507 | + _to_consumes = [f"{k}->{v}" for k, v in self.to_consume.items()] |
| 508 | + _consumed = [f"{k}->{v}" for k, v in self.consumed.items()] |
| 509 | + _consumed_uncertain = [f"{k}->{v}" for k, v in self.consumed_uncertain.items()] |
507 | 510 | to_consumes = ", ".join(_to_consumes) |
508 | 511 | consumed = ", ".join(_consumed) |
509 | 512 | consumed_uncertain = ", ".join(_consumed_uncertain) |
510 | 513 | return f""" |
511 | 514 | to_consume : {to_consumes} |
512 | 515 | consumed : {consumed} |
513 | 516 | consumed_uncertain: {consumed_uncertain} |
514 | | -scope_type : {self._atomic.scope_type} |
| 517 | +scope_type : {self.scope_type} |
515 | 518 | """ |
516 | 519 |
|
517 | | - def __iter__(self) -> Iterator[Any]: |
518 | | - return iter(self._atomic) |
519 | | - |
520 | | - @property |
521 | | - def to_consume(self) -> Consumption: |
522 | | - return self._atomic.to_consume |
523 | | - |
524 | | - @property |
525 | | - def consumed(self) -> Consumption: |
526 | | - return self._atomic.consumed |
527 | | - |
528 | | - @property |
529 | | - def consumed_uncertain(self) -> Consumption: |
530 | | - """Retrieves nodes filtered out by get_next_to_consume() that may not |
531 | | - have executed. |
532 | | -
|
533 | | - These include nodes such as statements in except blocks, or statements |
534 | | - in try blocks (when evaluating their corresponding except and finally |
535 | | - blocks). Checkers that want to treat the statements as executed |
536 | | - (e.g. for unused-variable) may need to add them back. |
537 | | - """ |
538 | | - return self._atomic.consumed_uncertain |
539 | | - |
540 | | - @property |
541 | | - def scope_type(self) -> str: |
542 | | - return self._atomic.scope_type |
543 | | - |
544 | 520 | def mark_as_consumed(self, name: str, consumed_nodes: list[nodes.NodeNG]) -> None: |
545 | 521 | """Mark the given nodes as consumed for the name. |
546 | 522 |
|
@@ -3314,7 +3290,8 @@ def _check_classdef_metaclasses( |
3314 | 3290 | name = METACLASS_NAME_TRANSFORMS.get(name, name) |
3315 | 3291 | if name: |
3316 | 3292 | # check enclosing scopes starting from most local |
3317 | | - for scope_locals, _, _, _ in self._to_consume[::-1]: |
| 3293 | + for to_consume in self._to_consume[::-1]: |
| 3294 | + scope_locals = to_consume.to_consume |
3318 | 3295 | found_nodes = scope_locals.get(name, []) |
3319 | 3296 | for found_node in found_nodes: |
3320 | 3297 | if found_node.lineno <= klass.lineno: |
|
0 commit comments