55
55
56
56
_logger = logging .getLogger (__name__ )
57
57
_found_deprecated_tags : set [str ] = set ()
58
- _noqa_comment_re = re .compile (r"^# noqa(\s|:)" )
58
+ _noqa_comment_re = re .compile (r"^\s*# noqa(\s|:)" , flags = re .MULTILINE )
59
+ _noqa_comment_line_re = re .compile (r"^\s*# noqa(\s|:).*$" )
59
60
60
61
# playbook: Sequence currently expects only instances of one of the two
61
62
# classes below but we should consider avoiding this chimera.
@@ -257,6 +258,25 @@ def get_nested_tasks(task: Any) -> Generator[Any, None, None]:
257
258
yield task
258
259
259
260
261
+ def _continue_skip_next_lines (
262
+ lintable : Lintable ,
263
+ ) -> None :
264
+ """When a line only contains a noqa comment (and possibly indentation), add the skip also to the next non-empty line."""
265
+ # If line starts with _noqa_comment_line_re, add next non-empty line to same lintable.line_skips
266
+ line_content = lintable .content .splitlines ()
267
+ for line_no in list (lintable .line_skips .keys ()):
268
+ if _noqa_comment_line_re .fullmatch (line_content [line_no - 1 ]):
269
+ # Find next non-empty line
270
+ next_line_no = line_no
271
+ while next_line_no < len (line_content ) and not line_content [next_line_no ].strip ():
272
+ next_line_no += 1
273
+ if next_line_no >= len (line_content ):
274
+ continue
275
+ lintable .line_skips [next_line_no + 1 ].update (
276
+ lintable .line_skips [line_no ],
277
+ )
278
+
279
+
260
280
def _get_rule_skips_from_yaml (
261
281
yaml_input : Sequence [Any ],
262
282
lintable : Lintable ,
@@ -268,7 +288,13 @@ def _get_rule_skips_from_yaml(
268
288
return []
269
289
270
290
def traverse_yaml (obj : Any ) -> None :
271
- for entry in obj .ca .items .values ():
291
+ traversable = list (obj .ca .items .values ())
292
+ if obj .ca .comment :
293
+ traversable .append (obj .ca .comment )
294
+ for entry in traversable :
295
+ # flatten all lists we might have in entries. Some arcane ruamel CommentedMap magic
296
+ entry = [item for sublist in entry if sublist is not None
297
+ for item in (sublist if isinstance (sublist , list ) else [sublist ])]
272
298
for v in entry :
273
299
if isinstance (v , CommentToken ):
274
300
comment_str = v .value
@@ -298,6 +324,7 @@ def traverse_yaml(obj: Any) -> None:
298
324
for comment_obj_str in yaml_comment_obj_strings :
299
325
for line in comment_obj_str .split (r"\n" ):
300
326
rule_id_list .extend (get_rule_skips_from_line (line , lintable = lintable ))
327
+ _continue_skip_next_lines (lintable )
301
328
302
329
return [normalize_tag (tag ) for tag in rule_id_list ]
303
330
0 commit comments