Repository navigation
Handle needs_functions callables without __name__ and non-iterable configurations (#2073) - #2107
Open
wayu15244 wants to merge 1 commit into
Conversation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #2073.
Problem / Root Cause
In
sphinx_needs/needs.py:merge_default_configs, registering functions fromneeds_config._functionshad two failure modes:_Config.add_function(self, function, name=None)directly accessedfunction.__name__. When given callable objects that do not have__name__directly attached (such asfunctools.partialor callable class instances), it raisedAttributeError: 'functools.partial' object has no attribute '__name__'.needs_functionswas configured asNoneor a bare callable instead of a list/tuple, iterating overneeds_config._functionsraisedTypeError: 'NoneType' object is not iterableor'function' object is not iterable.Solution
sphinx_needs/config.py: usegetattr(function, '__name__', None)inadd_function. Ifnameis omitted and the callable has no__name__, emit aneeds.configwarning and return instead of raising an unhandledAttributeError.sphinx_needs/needs.py: checkisinstance(needs_config._functions, (list, tuple))before iterating. For each entry, checkgetattr(needs_func, '__name__', None)and emit an informative warning advising users to provide a callable with__name__or register viaadd_dynamic_function(func, name=...).add_dynamic_functionto successfully register callables without__name__(such asfunctools.partial) when an explicitnameis provided.Tests Added
test_needs_functions_entry_without_name_warns_and_is_ignored: verifies a callable without__name__inneeds_functionswarns and is ignored without crashing.test_needs_functions_none_value_does_not_crash: verifiesneeds_functions = Nonedoes not crash.test_needs_functions_bare_callable_value_does_not_crash: verifiesneeds_functions = funcdoes not crash.test_add_dynamic_function_allows_callables_without_name: verifies registering afunctools.partialviaadd_dynamic_function(..., name='partial_func')executes and evaluates correctly in needs.Validation
uv run pytest packages/sphinx-needs/tests/test_needs_from_toml_functions.py: 14 passed.uv run pytest packages/sphinx-needs/tests/test_dynamic_functions.py: 37 passed.