-
-
Notifications
You must be signed in to change notification settings - Fork 385
/
types.py
281 lines (206 loc) · 6.31 KB
/
types.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
"""
This module contains knowledge about the most important types that we use.
There are also different :term:`visitor` specific types
that are defined and use exclusively in that file.
Policy
~~~~~~
If any of the following statements is true, move the type to this file:
- if type is used in multiple files
- if type is complex enough it has to be documented
- if type is very important for the public API
final
~~~~~
As you can see in the source code almost everything
is marked as ``@final`` or ``Final``.
It means that this value cannot be subclassed or reassigned.
This it only a ``mypy`` feature, it does not affect ``python`` runtime.
We do this, because we value composition over inheritance.
And this ``@final`` decorators help you to define readable and clear APIs
for cases when inheritance is used.
See also:
My guide about ``@final`` type in ``python``:
https://sobolevn.me/2018/07/real-python-contants
Reference
~~~~~~~~~
"""
import ast
from typing import Tuple, Type, Union
from typing_extensions import Protocol, TypeAlias
#: We use this type to represent all string-like nodes.
AnyText: TypeAlias = Union[ast.Str, ast.Bytes]
#: In cases we need to work with both import types.
AnyImport: TypeAlias = Union[ast.Import, ast.ImportFrom]
#: In cases we need to work with both function definitions.
AnyFunctionDef: TypeAlias = Union[ast.FunctionDef, ast.AsyncFunctionDef]
#: In cases we need to work with all function definitions (including lambdas).
AnyFunctionDefAndLambda: TypeAlias = Union[AnyFunctionDef, ast.Lambda]
#: In cases we need to work with both forms of if functions.
AnyIf: TypeAlias = Union[ast.If, ast.IfExp]
#: In cases we need to work with both sync and async loops.
AnyFor: TypeAlias = Union[ast.For, ast.AsyncFor]
#: In case we need to work with any loop: sync, async, and while.
AnyLoop: TypeAlias = Union[AnyFor, ast.While]
#: This is how you can define a variable in Python.
AnyVariableDef: TypeAlias = Union[ast.Name, ast.Attribute, ast.ExceptHandler]
#: All different comprehension types in one place.
AnyComprehension: TypeAlias = Union[
ast.ListComp,
ast.DictComp,
ast.SetComp,
ast.GeneratorExp,
]
#: In cases we need to work with both sync and async context managers.
AnyWith: TypeAlias = Union[ast.With, ast.AsyncWith]
#: When we search for assign elements, we also need typed assign.
AnyAssign: TypeAlias = Union[ast.Assign, ast.AnnAssign]
#: When we search for assign elements, we also need typed assign.
AnyAssignWithWalrus: TypeAlias = Union[AnyAssign, ast.NamedExpr]
#: In cases we need to work with both access types.
AnyAccess: TypeAlias = Union[
ast.Attribute,
ast.Subscript,
]
#: In case we need to handle types that can be chained.
AnyChainable: TypeAlias = Union[
ast.Attribute,
ast.Subscript,
ast.Call,
]
#: Tuple of AST node types for declarative syntax.
AnyNodes: TypeAlias = Tuple[Type[ast.AST], ...]
#: We use this type to work with any text-like values. Related to `AnyText`.
AnyTextPrimitive: TypeAlias = Union[str, bytes]
#: That's how we define context of operations.
ContextNodes: TypeAlias = Union[
ast.Module,
ast.ClassDef,
AnyFunctionDef,
]
#: Flake8 API format to return error messages.
CheckResult: TypeAlias = Tuple[int, int, str, type]
class ConfigurationOptions(Protocol):
"""
Provides structure for the options we use in our checker and visitors.
Then this protocol is passed to each individual visitor.
It uses structural sub-typing, and does not represent any kind of a real
class or structure.
We use ``@property`` decorator here instead of regular attributes,
because we need to explicitly mark these atrtibutes as read-only.
See also:
https://mypy.readthedocs.io/en/latest/protocols.html
"""
def __hash__(self) -> int:
"""We need these options to be hashable."""
# General:
@property
def min_name_length(self) -> int:
...
@property
def i_control_code(self) -> bool:
...
@property
def max_name_length(self) -> int:
...
@property
def max_noqa_comments(self) -> int:
...
@property
def nested_classes_whitelist(self) -> Tuple[str, ...]:
...
@property
def forbidden_inline_ignore(self) -> Tuple[str, ...]:
...
@property
def allowed_domain_names(self) -> Tuple[str, ...]:
...
@property
def forbidden_domain_names(self) -> Tuple[str, ...]:
...
# Complexity:
@property
def max_arguments(self) -> int:
...
@property
def max_local_variables(self) -> int:
...
@property
def max_returns(self) -> int:
...
@property
def max_expressions(self) -> int:
...
@property
def max_module_members(self) -> int:
...
@property
def max_methods(self) -> int:
...
@property
def max_line_complexity(self) -> int:
...
@property
def max_jones_score(self) -> int:
...
@property
def max_imports(self) -> int:
...
@property
def max_imported_names(self) -> int:
...
@property
def max_base_classes(self) -> int:
...
@property
def max_decorators(self) -> int:
...
@property
def max_string_usages(self) -> int:
...
@property
def max_awaits(self) -> int:
...
@property
def max_try_body_length(self) -> int:
...
@property
def max_module_expressions(self) -> int:
...
@property
def max_function_expressions(self) -> int:
...
@property
def max_asserts(self) -> int:
...
@property
def max_access_level(self) -> int:
...
@property
def max_attributes(self) -> int:
...
@property
def max_raises(self) -> int:
...
@property
def max_cognitive_score(self) -> int:
...
@property
def max_cognitive_average(self) -> int:
...
@property
def max_call_level(self) -> int:
...
@property
def max_annotation_complexity(self) -> int:
...
@property
def max_import_from_members(self) -> int:
...
@property
def max_tuple_unpack_length(self) -> int:
...
@property
def show_violation_links(self) -> bool:
...
@property
def exps_for_one_empty_line(self) -> int:
...