35
35
from domdf_python_tools .paths import PathPlus
36
36
from domdf_python_tools .typing import PathLike
37
37
38
- __all__ = [ "AnnotationVisitor" , "Error" , "Plugin" , "check_file" , "indent_join" ]
38
+ __all__ = ( "AnnotationVisitor" , "Error" , "Plugin" , "check_file" , "indent_join" )
39
39
40
40
__author__ : str = "Dominic Davis-Foster"
41
41
__copyright__ : str = "2022 Dominic Davis-Foster"
@@ -112,9 +112,11 @@ def run(self) -> Generator[Tuple[int, int, str, Type[Any]], None, None]:
112
112
113
113
offences = list (error .offences )
114
114
115
+ # pylint: disable=loop-global-usage
115
116
missing_return_type = _no_return_annotation in offences
116
117
if missing_return_type :
117
118
offences .remove (_no_return_annotation )
119
+ # pylint: enable=loop-global-usage
118
120
119
121
if offences :
120
122
yield (
@@ -125,15 +127,9 @@ def run(self) -> Generator[Tuple[int, int, str, Type[Any]], None, None]:
125
127
)
126
128
127
129
if missing_return_type :
128
- yield (
129
- error .lineno ,
130
- error .col_offset or 0 ,
131
- f"MAN002 Function { error .function !r} { _no_return_annotation } " ,
132
- type (self ),
133
- )
134
-
130
+ msg = f"MAN002 Function { error .function !r} { _no_return_annotation } " # pylint: disable=loop-global-usage
131
+ yield error .lineno , error .col_offset or 0 , msg , type (self )
135
132
136
- pytest_fixture_whitelist = ["monkeypatch" , "capsys" , "request" , "pytestconfig" ]
137
133
138
134
_no_return_annotation = "missing return annotation"
139
135
@@ -148,6 +144,8 @@ class AnnotationVisitor(ast.NodeVisitor):
148
144
_state : List [str ]
149
145
_errors : List [Error ]
150
146
147
+ pytest_fixture_whitelist = ("monkeypatch" , "capsys" , "request" , "pytestconfig" )
148
+
151
149
allowed_no_return_type = {
152
150
"__init__" ,
153
151
"__exit__" ,
@@ -215,37 +213,41 @@ def visit_FunctionDef(self, function: ast.FunctionDef) -> None:
215
213
216
214
offending_arguments = []
217
215
216
+ AttributeNode , NameNode , CallNode = ast .Attribute , ast .Name , ast .Call
217
+
218
218
decorators = function .decorator_list
219
219
is_fixture = False
220
220
if decorators :
221
221
for deco in decorators :
222
- if isinstance (deco , ast . Name ):
222
+ if isinstance (deco , NameNode ):
223
223
if deco .id == "fixture" :
224
224
is_fixture = True
225
- elif isinstance (deco , ast . Attribute ):
226
- if isinstance (deco .value , ast . Name ):
225
+ elif isinstance (deco , AttributeNode ):
226
+ if isinstance (deco .value , NameNode ):
227
227
if deco .value .id == "pytest" and deco .attr == "fixture" :
228
228
is_fixture = True
229
- elif isinstance (deco , ast . Call ):
230
- if isinstance (deco .func , ast . Attribute ):
231
- if isinstance (deco .func .value , ast . Name ):
229
+ elif isinstance (deco , CallNode ):
230
+ if isinstance (deco .func , AttributeNode ):
231
+ if isinstance (deco .func .value , NameNode ):
232
232
if deco .func .value .id == "pytest" and deco .func .attr == "fixture" :
233
233
is_fixture = True
234
234
235
235
arg : ast .arg
236
236
for arg in args .args :
237
237
if arg .annotation is None :
238
+ # pylint: disable=loop-invariant-statement
238
239
if arg .arg in {"self" , "cls" }:
239
240
continue
240
241
241
- if is_test and arg .arg in pytest_fixture_whitelist :
242
+ if is_test and arg .arg in self . pytest_fixture_whitelist :
242
243
continue
243
244
244
- elif is_fixture and arg .arg in pytest_fixture_whitelist :
245
+ elif is_fixture and arg .arg in self . pytest_fixture_whitelist :
245
246
continue
246
247
247
248
elif function_name in {"__exit__" }:
248
249
continue
250
+ # pylint: enable=loop-invariant-statement
249
251
250
252
offending_arguments .append (f"argument { arg .arg !r} is missing a type annotation" )
251
253
0 commit comments