|
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