11
11
import shutil
12
12
import subprocess
13
13
import sys
14
+ from typing import TYPE_CHECKING , Any , Callable , Optional , Tuple , Union
14
15
15
16
import astroid
16
17
from astroid import nodes
17
18
19
+ if TYPE_CHECKING :
20
+ from pylint .pyreverse .diadefslib import DiaDefGenerator
21
+ from pylint .pyreverse .diagrams import ClassDiagram , PackageDiagram
22
+ from pylint .pyreverse .inspector import Linker
23
+
24
+ _CallbackT = Callable [
25
+ [nodes .NodeNG ],
26
+ Union [Tuple [ClassDiagram ], Tuple [PackageDiagram , ClassDiagram ], None ],
27
+ ]
28
+ _CallbackTupleT = Tuple [Optional [_CallbackT ], Optional [_CallbackT ]]
29
+
30
+
18
31
RCFILE = ".pyreverserc"
19
32
20
33
@@ -46,7 +59,7 @@ def insert_default_options() -> None:
46
59
PROTECTED = re .compile (r"^_\w*$" )
47
60
48
61
49
- def get_visibility (name ) :
62
+ def get_visibility (name : str ) -> str :
50
63
"""Return the visibility from a name: public, protected, private or special."""
51
64
if SPECIAL .match (name ):
52
65
visibility = "special"
@@ -60,37 +73,18 @@ def get_visibility(name):
60
73
return visibility
61
74
62
75
63
- ABSTRACT = re .compile (r"^.*Abstract.*" )
64
- FINAL = re .compile (r"^[^\W\da-z]*$" )
65
-
66
-
67
- def is_abstract (node ):
68
- """Return true if the given class node correspond to an abstract class
69
- definition.
70
- """
71
- return ABSTRACT .match (node .name )
72
-
73
-
74
- def is_final (node ):
75
- """Return true if the given class/function node correspond to final
76
- definition.
77
- """
78
- return FINAL .match (node .name )
79
-
80
-
81
- def is_interface (node ):
76
+ def is_interface (node : nodes .ClassDef ) -> bool :
82
77
# bw compatibility
83
78
return node .type == "interface"
84
79
85
80
86
- def is_exception (node ) :
81
+ def is_exception (node : nodes . ClassDef ) -> bool :
87
82
# bw compatibility
88
83
return node .type == "exception"
89
84
90
85
91
86
# Helpers #####################################################################
92
87
93
- _CONSTRUCTOR = 1
94
88
_SPECIAL = 2
95
89
_PROTECTED = 4
96
90
_PRIVATE = 8
@@ -111,7 +105,7 @@ def is_exception(node):
111
105
class FilterMixIn :
112
106
"""Filter nodes according to a mode and nodes' visibility."""
113
107
114
- def __init__ (self , mode ) :
108
+ def __init__ (self , mode : str ) -> None :
115
109
"""Init filter modes."""
116
110
__mode = 0
117
111
for nummod in mode .split ("+" ):
@@ -121,7 +115,7 @@ def __init__(self, mode):
121
115
print (f"Unknown filter mode { ex } " , file = sys .stderr )
122
116
self .__mode = __mode
123
117
124
- def show_attr (self , node ) :
118
+ def show_attr (self , node : nodes . NodeNG | str ) -> bool :
125
119
"""Return true if the node should be treated."""
126
120
visibility = get_visibility (getattr (node , "name" , node ))
127
121
return not self .__mode & VIS_MOD [visibility ]
@@ -137,11 +131,11 @@ class ASTWalker:
137
131
the node in lower case
138
132
"""
139
133
140
- def __init__ (self , handler ) :
134
+ def __init__ (self , handler : DiaDefGenerator | Linker | LocalsVisitor ) -> None :
141
135
self .handler = handler
142
- self ._cache = {}
136
+ self ._cache : dict [ type [ nodes . NodeNG ], _CallbackTupleT ] = {}
143
137
144
- def walk (self , node , _done = None ):
138
+ def walk (self , node : nodes . NodeNG , _done : set [ nodes . NodeNG ] | None = None ) -> None :
145
139
"""Walk on the tree from <node>, getting callbacks from handler."""
146
140
if _done is None :
147
141
_done = set ()
@@ -155,7 +149,7 @@ def walk(self, node, _done=None):
155
149
self .leave (node )
156
150
assert node .parent is not node
157
151
158
- def get_callbacks (self , node ) :
152
+ def get_callbacks (self , node : nodes . NodeNG ) -> _CallbackTupleT :
159
153
"""Get callbacks from handler for the visited node."""
160
154
klass = node .__class__
161
155
methods = self ._cache .get (klass )
@@ -173,13 +167,13 @@ def get_callbacks(self, node):
173
167
e_method , l_method = methods
174
168
return e_method , l_method
175
169
176
- def visit (self , node ) :
170
+ def visit (self , node : nodes . NodeNG ) -> Any :
177
171
"""Walk on the tree from <node>, getting callbacks from handler."""
178
172
method = self .get_callbacks (node )[0 ]
179
173
if method is not None :
180
174
method (node )
181
175
182
- def leave (self , node ) :
176
+ def leave (self , node : nodes . NodeNG ) -> None :
183
177
"""Walk on the tree from <node>, getting callbacks from handler."""
184
178
method = self .get_callbacks (node )[1 ]
185
179
if method is not None :
@@ -189,11 +183,11 @@ def leave(self, node):
189
183
class LocalsVisitor (ASTWalker ):
190
184
"""Visit a project by traversing the locals dictionary."""
191
185
192
- def __init__ (self ):
186
+ def __init__ (self ) -> None :
193
187
super ().__init__ (self )
194
- self ._visited = set ()
188
+ self ._visited : set [ nodes . NodeNG ] = set ()
195
189
196
- def visit (self , node ) :
190
+ def visit (self , node : nodes . NodeNG ) -> Any :
197
191
"""Launch the visit starting from the given node."""
198
192
if node in self ._visited :
199
193
return None
@@ -253,7 +247,7 @@ def get_annotation(
253
247
return ann
254
248
255
249
256
- def infer_node (node : nodes .AssignAttr | nodes .AssignName ) -> set :
250
+ def infer_node (node : nodes .AssignAttr | nodes .AssignName ) -> set [ Any ] :
257
251
"""Return a set containing the node annotation if it exists
258
252
otherwise return a set of the inferred types using the NodeNG.infer method.
259
253
"""
@@ -269,7 +263,7 @@ def infer_node(node: nodes.AssignAttr | nodes.AssignName) -> set:
269
263
return {ann } if ann else set ()
270
264
271
265
272
- def check_graphviz_availability ():
266
+ def check_graphviz_availability () -> None :
273
267
"""Check if the ``dot`` command is available on the machine.
274
268
275
269
This is needed if image output is desired and ``dot`` is used to convert
0 commit comments