Skip to content

Handle needs_functions callables without __name__ and non-iterable configurations (#2073) - #2107

Open
wayu15244 wants to merge 1 commit into
useblocks:masterfrom
wayu15244:fix/issue-2073-needs-functions-callable-validation
Open

wayu15244 wants to merge 1 commit into
useblocks:masterfrom
wayu15244:fix/issue-2073-needs-functions-callable-validation

Conversation

@wayu15244

Copy link
Copy Markdown

Summary

Closes #2073.

Problem / Root Cause

In sphinx_needs/needs.py:merge_default_configs, registering functions from needs_config._functions had two failure modes:

  1. _Config.add_function(self, function, name=None) directly accessed function.__name__. When given callable objects that do not have __name__ directly attached (such as functools.partial or callable class instances), it raised AttributeError: 'functools.partial' object has no attribute '__name__'.
  2. If needs_functions was configured as None or a bare callable instead of a list/tuple, iterating over needs_config._functions raised TypeError: 'NoneType' object is not iterable or 'function' object is not iterable.

Solution

  • In sphinx_needs/config.py: use getattr(function, '__name__', None) in add_function. If name is omitted and the callable has no __name__, emit a needs.config warning and return instead of raising an unhandled AttributeError.
  • In sphinx_needs/needs.py: check isinstance(needs_config._functions, (list, tuple)) before iterating. For each entry, check getattr(needs_func, '__name__', None) and emit an informative warning advising users to provide a callable with __name__ or register via add_dynamic_function(func, name=...).
  • Allows add_dynamic_function to successfully register callables without __name__ (such as functools.partial) when an explicit name is provided.

Tests Added

  • test_needs_functions_entry_without_name_warns_and_is_ignored: verifies a callable without __name__ in needs_functions warns and is ignored without crashing.
  • test_needs_functions_none_value_does_not_crash: verifies needs_functions = None does not crash.
  • test_needs_functions_bare_callable_value_does_not_crash: verifies needs_functions = func does not crash.
  • test_add_dynamic_function_allows_callables_without_name: verifies registering a functools.partial via add_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.

@github-actions github-actions Bot added the pkg: sphinx-needs The sphinx-needs distribution (packages/sphinx-needs): its code, tests and docs label Oct 7, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg: sphinx-needs The sphinx-needs distribution (packages/sphinx-needs): its code, tests and docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

needs_functions entries that are callable without a __name__, or a non-iterable value, still crash the build

1 participant