99from types import CodeType
1010from typing import Any , Iterable , TypedDict , TypeVar
1111
12+ from docutils import nodes
1213from docutils .parsers .rst import directives
1314from sphinx .application import Sphinx
1415from sphinx .util .docutils import SphinxDirective
@@ -180,7 +181,10 @@ def process_filters(
180181 found_needs_by_options .append (need_info )
181182 # Get need by filter string
182183 found_needs_by_string = filter_needs (
183- all_needs_incl_parts , needs_config , filter_data ["filter" ]
184+ all_needs_incl_parts ,
185+ needs_config ,
186+ filter_data ["filter" ],
187+ location = (filter_data ["docname" ], filter_data ["lineno" ]),
184188 )
185189 # Make an intersection of both lists
186190 found_needs = intersection_of_need_results (
@@ -190,7 +194,10 @@ def process_filters(
190194 # There is no other config as the one for filter string.
191195 # So we only need this result.
192196 found_needs = filter_needs (
193- all_needs_incl_parts , needs_config , filter_data ["filter" ]
197+ all_needs_incl_parts ,
198+ needs_config ,
199+ filter_data ["filter" ],
200+ location = (filter_data ["docname" ], filter_data ["lineno" ]),
194201 )
195202 else :
196203 # Provides only a copy of needs to avoid data manipulations.
@@ -296,6 +303,9 @@ def filter_needs(
296303 config : NeedsSphinxConfig ,
297304 filter_string : None | str = "" ,
298305 current_need : NeedsInfoType | None = None ,
306+ * ,
307+ location : tuple [str , int | None ] | nodes .Node | None = None ,
308+ append_warning : str = "" ,
299309) -> list [V ]:
300310 """
301311 Filters given needs based on a given filter string.
@@ -305,6 +315,8 @@ def filter_needs(
305315 :param config: NeedsSphinxConfig object
306316 :param filter_string: strings, which gets evaluated against each need
307317 :param current_need: current need, which uses the filter.
318+ :param location: source location for error reporting (docname, line number)
319+ :param append_warning: additional text to append to any failed filter warning
308320
309321 :return: list of found needs
310322 """
@@ -328,13 +340,15 @@ def filter_needs(
328340 ):
329341 found_needs .append (filter_need )
330342 except Exception as e :
331- if not error_reported : # Let's report a filter-problem only onces
332- location = (
333- (current_need ["docname" ], current_need ["lineno" ])
334- if current_need
335- else None
343+ if not error_reported : # Let's report a filter-problem only once
344+ if append_warning :
345+ append_warning = f" { append_warning } "
346+ log .warning (
347+ f"{ e } { append_warning } [needs.filter]" ,
348+ type = "needs" ,
349+ subtype = "filter" ,
350+ location = location ,
336351 )
337- log .warning (str (e ) + " [needs]" , type = "needs" , location = location )
338352 error_reported = True
339353
340354 return found_needs
@@ -381,5 +395,5 @@ def filter_single_need(
381395 else :
382396 result = bool (eval (filter_string , filter_context ))
383397 except Exception as e :
384- raise NeedsInvalidFilter (f"Filter { filter_string } not valid. Error: { e } ." )
398+ raise NeedsInvalidFilter (f"Filter { filter_string !r } not valid. Error: { e } ." )
385399 return result
0 commit comments