@@ -82,6 +82,7 @@ class Options(Protocol):
8282
8383 noqa_require_code : bool
8484 noqa_include_name : bool
85+ external : list [str ]
8586
8687
8788class NoqaFilter :
@@ -91,6 +92,7 @@ class NoqaFilter:
9192 version : ClassVar [str ] = package_version
9293 plugin_name : ClassVar [str ]
9394 require_code : ClassVar [bool ]
95+ external : list [str ]
9496 _filters : ClassVar [list [NoqaFilter ]] = []
9597
9698 tree : ast .AST
@@ -111,12 +113,18 @@ def add_options(cls, option_manager: flake8.options.manager.OptionManager) -> No
111113 option_manager .add_option ('--noqa-no-include-name' , default = None , action = 'store_false' ,
112114 parse_from_config = False , dest = 'noqa_include_name' ,
113115 help = 'Remove plugin name from messages' )
116+ option_manager .add_option ('--noqa-external' , default = [], comma_separated_list = True ,
117+ parse_from_config = True , dest = 'external' ,
118+ help = 'List of codes comming from non-Flake8 tools. Use this to allow '
119+ 'interoperability between flake8-noqa and non-Flake8 tools also using `# noqa` '
120+ 'suppression comments.' )
114121
115122 @classmethod
116123 def parse_options (cls , options : Options ) -> None :
117124 """Parse plugin options."""
118125 cls .plugin_name = (' (' + cls .name + ')' ) if (options .noqa_include_name ) else ''
119126 cls .require_code = options .noqa_require_code
127+ cls .external = options .external
120128
121129 @classmethod
122130 def filters (cls ) -> Sequence [NoqaFilter ]:
@@ -140,32 +148,31 @@ def __iter__(self) -> Iterator[tuple[int, int, str, Any]]:
140148 def _message (self , token : tokenize .TokenInfo , message : Message , ** kwargs ) -> tuple [int , int , str , Any ]:
141149 return (token .start [0 ], token .start [1 ], f'{ message .code } { self .plugin_name } { message .text (** kwargs )} ' , type (self ))
142150
151+ def _is_external_code (self , code : str ) -> bool :
152+ return any (code .startswith (external_code ) for external_code in self .external )
153+
143154 def violations (self ) -> Iterator [tuple [int , int , str , Any ]]:
144155 """Private iterator to return violations."""
145156 for comment in InlineComment .file_comments (self .filename ):
146- reports = Report .reports_from (self .filename , comment .start_line , comment .end_line )
157+ reports = set ( Report .reports_from (self .filename , comment .start_line , comment .end_line ) )
147158 comment_codes = set (comment .code_list )
148159 if (comment_codes ):
149- matched_codes : set [str ] = set ()
150- for code in reports :
151- if (code in comment_codes ):
152- matched_codes .add (code )
153- if (matched_codes ):
154- if (len (matched_codes ) < len (comment_codes )):
155- unmatched_codes = comment_codes - matched_codes
156- yield self ._message (comment .token , Message .NOQA_UNMATCHED_CODES ,
157- comment = comment .text , unmatched = ', ' .join (unmatched_codes ),
158- plural = 'codes' if (1 < len (unmatched_codes )) else 'code' )
159- else :
160+ external_comment_codes = {code for code in comment_codes if self ._is_external_code (code )}
161+ matched_and_external_codes = (reports & comment_codes ) | external_comment_codes
162+ if (not matched_and_external_codes ):
160163 yield self ._message (comment .token , Message .NOQA_NO_MATCHING_CODES , comment = comment .text )
161-
162- pass
164+ else :
165+ unmatched_codes = comment_codes - matched_and_external_codes
166+ if (unmatched_codes ):
167+ yield self ._message (comment .token , Message .NOQA_UNMATCHED_CODES ,
168+ comment = comment .text , unmatched = ', ' .join (unmatched_codes ),
169+ plural = 'codes' if (1 < len (unmatched_codes )) else 'code' )
163170 else : # blanket noqa
164171 if (reports ):
165172 if (self .require_code ):
166173 yield self ._message (comment .token , Message .NOQA_REQUIRE_CODE ,
167174 comment = comment .text , noqa_strip = comment .noqa .strip (),
168- codes = ', ' .join (sorted (set ( reports ) )))
175+ codes = ', ' .join (sorted (reports )))
169176
170177 else :
171178 yield self ._message (comment .token , Message .NOQA_NO_VIOLATIONS , comment = comment .text )
0 commit comments