@@ -77,6 +77,7 @@ class _ParseTimeoutError(Exception):
7777
7878FunctionNode = ast .FunctionDef | ast .AsyncFunctionDef
7979_NamedDeclarationNode = FunctionNode | ast .ClassDef
80+ _DeclarationTokenIndexKey = tuple [int , int , str ]
8081
8182
8283def _consumed_cpu_seconds (resource_module : object ) -> float :
@@ -177,7 +178,10 @@ def _declaration_token_index(
177178 start_line : int ,
178179 start_col : int ,
179180 declaration_token : str ,
181+ source_token_index : Mapping [_DeclarationTokenIndexKey , int ] | None = None ,
180182) -> int | None :
183+ if source_token_index is not None :
184+ return source_token_index .get ((start_line , start_col , declaration_token ))
181185 for idx , token in enumerate (source_tokens ):
182186 if token .start != (start_line , start_col ):
183187 continue
@@ -186,6 +190,19 @@ def _declaration_token_index(
186190 return None
187191
188192
193+ def _build_declaration_token_index (
194+ source_tokens : tuple [tokenize .TokenInfo , ...],
195+ ) -> Mapping [_DeclarationTokenIndexKey , int ]:
196+ indexed : dict [_DeclarationTokenIndexKey , int ] = {}
197+ for idx , token in enumerate (source_tokens ):
198+ if token .type != tokenize .NAME :
199+ continue
200+ if token .string not in {"def" , "async" , "class" }:
201+ continue
202+ indexed [(token .start [0 ], token .start [1 ], token .string )] = idx
203+ return indexed
204+
205+
189206def _scan_declaration_colon_line (
190207 * ,
191208 source_tokens : tuple [tokenize .TokenInfo , ...],
@@ -223,6 +240,7 @@ def _declaration_end_line(
223240 node : ast .AST ,
224241 * ,
225242 source_tokens : tuple [tokenize .TokenInfo , ...],
243+ source_token_index : Mapping [_DeclarationTokenIndexKey , int ] | None = None ,
226244) -> int :
227245 start_line = int (getattr (node , "lineno" , 0 ))
228246 start_col = int (getattr (node , "col_offset" , 0 ))
@@ -235,6 +253,7 @@ def _declaration_end_line(
235253 start_line = start_line ,
236254 start_col = start_col ,
237255 declaration_token = declaration_token ,
256+ source_token_index = source_token_index ,
238257 )
239258 if start_index is None :
240259 return _fallback_declaration_end_line (node , start_line = start_line )
@@ -788,7 +807,9 @@ def _collect_declaration_targets(
788807 filepath : str ,
789808 module_name : str ,
790809 collector : _QualnameCollector ,
791- source_tokens : tuple [tokenize .TokenInfo , ...],
810+ source_tokens : tuple [tokenize .TokenInfo , ...] = (),
811+ source_token_index : Mapping [_DeclarationTokenIndexKey , int ] | None = None ,
812+ include_inline_lines : bool = False ,
792813) -> tuple [DeclarationTarget , ...]:
793814 declarations : list [DeclarationTarget ] = []
794815
@@ -797,9 +818,14 @@ def _collect_declaration_targets(
797818 end = int (getattr (node , "end_lineno" , 0 ))
798819 if start <= 0 or end <= 0 :
799820 continue
800- declaration_end_line = _declaration_end_line (
801- node ,
802- source_tokens = source_tokens ,
821+ declaration_end_line = (
822+ _declaration_end_line (
823+ node ,
824+ source_tokens = source_tokens ,
825+ source_token_index = source_token_index ,
826+ )
827+ if include_inline_lines
828+ else None
803829 )
804830 kind : Literal ["function" , "method" ] = (
805831 "method" if "." in local_name else "function"
@@ -820,9 +846,14 @@ def _collect_declaration_targets(
820846 end = int (getattr (class_node , "end_lineno" , 0 ))
821847 if start <= 0 or end <= 0 :
822848 continue
823- declaration_end_line = _declaration_end_line (
824- class_node ,
825- source_tokens = source_tokens ,
849+ declaration_end_line = (
850+ _declaration_end_line (
851+ class_node ,
852+ source_tokens = source_tokens ,
853+ source_token_index = source_token_index ,
854+ )
855+ if include_inline_lines
856+ else None
826857 )
827858 declarations .append (
828859 DeclarationTarget (
@@ -849,6 +880,42 @@ def _collect_declaration_targets(
849880 )
850881
851882
883+ def _build_suppression_index_for_source (
884+ * ,
885+ source : str ,
886+ filepath : str ,
887+ module_name : str ,
888+ collector : _QualnameCollector ,
889+ ) -> Mapping [SuppressionTargetKey , tuple [str , ...]]:
890+ suppression_directives = extract_suppression_directives (source )
891+ if not suppression_directives :
892+ return {}
893+
894+ needs_inline_binding = any (
895+ directive .binding == "inline" for directive in suppression_directives
896+ )
897+ source_tokens : tuple [tokenize .TokenInfo , ...] = ()
898+ source_token_index : Mapping [_DeclarationTokenIndexKey , int ] | None = None
899+ if needs_inline_binding :
900+ source_tokens = _source_tokens (source )
901+ if source_tokens :
902+ source_token_index = _build_declaration_token_index (source_tokens )
903+
904+ declaration_targets = _collect_declaration_targets (
905+ filepath = filepath ,
906+ module_name = module_name ,
907+ collector = collector ,
908+ source_tokens = source_tokens ,
909+ source_token_index = source_token_index ,
910+ include_inline_lines = needs_inline_binding ,
911+ )
912+ suppression_bindings = bind_suppressions_to_declarations (
913+ directives = suppression_directives ,
914+ declarations = declaration_targets ,
915+ )
916+ return build_suppression_index (suppression_bindings )
917+
918+
852919# =========================
853920# Public API
854921# =========================
@@ -883,7 +950,6 @@ def extract_units_and_stats_from_source(
883950 collector = _QualnameCollector ()
884951 collector .visit (tree )
885952 source_lines = source .splitlines ()
886- source_tokens = _source_tokens (source )
887953 source_line_count = len (source_lines )
888954
889955 is_test_file = is_test_filepath (filepath )
@@ -902,18 +968,12 @@ def extract_units_and_stats_from_source(
902968 protocol_symbol_aliases = _walk .protocol_symbol_aliases
903969 protocol_module_aliases = _walk .protocol_module_aliases
904970
905- suppression_directives = extract_suppression_directives ( source )
906- declaration_targets = _collect_declaration_targets (
971+ suppression_index = _build_suppression_index_for_source (
972+ source = source ,
907973 filepath = filepath ,
908974 module_name = module_name ,
909975 collector = collector ,
910- source_tokens = source_tokens ,
911- )
912- suppression_bindings = bind_suppressions_to_declarations (
913- directives = suppression_directives ,
914- declarations = declaration_targets ,
915976 )
916- suppression_index = build_suppression_index (suppression_bindings )
917977 class_names = frozenset (class_node .name for _ , class_node in collector .class_nodes )
918978 module_import_names = set (import_names )
919979 module_class_names = set (class_names )
0 commit comments