Skip to content

Commit a9d8364

Browse files
committed
Clean up and add typing to the mccabe extension
1 parent f874176 commit a9d8364

File tree

1 file changed

+49
-15
lines changed

1 file changed

+49
-15
lines changed

pylint/extensions/mccabe.py

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
from __future__ import annotations
88

9-
from typing import TYPE_CHECKING
9+
from collections.abc import Sequence
10+
from typing import TYPE_CHECKING, Any, TypeVar, Union
1011

1112
from astroid import nodes
1213
from mccabe import PathGraph as Mccabe_PathGraph
@@ -19,23 +20,48 @@
1920
if TYPE_CHECKING:
2021
from pylint.lint import PyLinter
2122

23+
_StatementNodes = Union[
24+
nodes.Assert,
25+
nodes.Assign,
26+
nodes.AugAssign,
27+
nodes.Delete,
28+
nodes.Raise,
29+
nodes.Yield,
30+
nodes.Import,
31+
nodes.Call,
32+
nodes.Subscript,
33+
nodes.Pass,
34+
nodes.Continue,
35+
nodes.Break,
36+
nodes.Global,
37+
nodes.Return,
38+
nodes.Expr,
39+
nodes.Await,
40+
]
41+
42+
_SubGraphNodes = Union[nodes.If, nodes.TryExcept, nodes.For, nodes.While]
43+
_AppendableNodeT = TypeVar(
44+
"_AppendableNodeT", bound=Union[_StatementNodes, nodes.While, nodes.FunctionDef]
45+
)
46+
2247

2348
class PathGraph(Mccabe_PathGraph):
24-
def __init__(self, node):
49+
def __init__(self, node: _SubGraphNodes | nodes.FunctionDef):
2550
super().__init__(name="", entity="", lineno=1)
2651
self.root = node
2752

2853

2954
class PathGraphingAstVisitor(Mccabe_PathGraphingAstVisitor):
30-
def __init__(self):
55+
def __init__(self) -> None:
3156
super().__init__()
3257
self._bottom_counter = 0
58+
self.graph: PathGraph | None = None
3359

34-
def default(self, node, *args):
60+
def default(self, node: nodes.NodeNG, *args: Any) -> None:
3561
for child in node.get_children():
3662
self.dispatch(child, *args)
3763

38-
def dispatch(self, node, *args):
64+
def dispatch(self, node: nodes.NodeNG, *args: Any) -> Any:
3965
self.node = node
4066
klass = node.__class__
4167
meth = self._cache.get(klass)
@@ -45,7 +71,7 @@ def dispatch(self, node, *args):
4571
self._cache[klass] = meth
4672
return meth(node, *args)
4773

48-
def visitFunctionDef(self, node):
74+
def visitFunctionDef(self, node: nodes.FunctionDef) -> None:
4975
if self.graph is not None:
5076
# closure
5177
pathnode = self._append_node(node)
@@ -65,7 +91,7 @@ def visitFunctionDef(self, node):
6591

6692
visitAsyncFunctionDef = visitFunctionDef
6793

68-
def visitSimpleStatement(self, node):
94+
def visitSimpleStatement(self, node: _StatementNodes) -> None:
6995
self._append_node(node)
7096

7197
visitAssert = (
@@ -74,8 +100,6 @@ def visitSimpleStatement(self, node):
74100
visitAugAssign
75101
) = (
76102
visitDelete
77-
) = (
78-
visitPrint
79103
) = (
80104
visitRaise
81105
) = (
@@ -94,20 +118,25 @@ def visitSimpleStatement(self, node):
94118
visitBreak
95119
) = visitGlobal = visitReturn = visitExpr = visitAwait = visitSimpleStatement
96120

97-
def visitWith(self, node):
121+
def visitWith(self, node: nodes.With) -> None:
98122
self._append_node(node)
99123
self.dispatch_list(node.body)
100124

101125
visitAsyncWith = visitWith
102126

103-
def _append_node(self, node):
104-
if not self.tail:
127+
def _append_node(self, node: _AppendableNodeT) -> _AppendableNodeT | None:
128+
if not self.tail or not self.graph:
105129
return None
106130
self.graph.connect(self.tail, node)
107131
self.tail = node
108132
return node
109133

110-
def _subgraph(self, node, name, extra_blocks=()):
134+
def _subgraph(
135+
self,
136+
node: _SubGraphNodes,
137+
name: str,
138+
extra_blocks: Sequence[nodes.ExceptHandler] = (),
139+
) -> None:
111140
"""Create the subgraphs representing any `if` and `for` statements."""
112141
if self.graph is None:
113142
# global loop
@@ -119,7 +148,12 @@ def _subgraph(self, node, name, extra_blocks=()):
119148
self._append_node(node)
120149
self._subgraph_parse(node, node, extra_blocks)
121150

122-
def _subgraph_parse(self, node, pathnode, extra_blocks):
151+
def _subgraph_parse(
152+
self,
153+
node: _SubGraphNodes,
154+
pathnode: _SubGraphNodes,
155+
extra_blocks: Sequence[nodes.ExceptHandler],
156+
) -> None:
123157
"""Parse the body and any `else` block of `if` and `for` statements."""
124158
loose_ends = []
125159
self.tail = node
@@ -135,7 +169,7 @@ def _subgraph_parse(self, node, pathnode, extra_blocks):
135169
loose_ends.append(self.tail)
136170
else:
137171
loose_ends.append(node)
138-
if node:
172+
if node and self.graph:
139173
bottom = f"{self._bottom_counter}"
140174
self._bottom_counter += 1
141175
for end in loose_ends:

0 commit comments

Comments
 (0)