You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
BUG: test_func_signature gives false failures on certain Python versions for nanobind-bound functions #449
On MLX, the test suite fails to recognise certain function signatures. For example: the stack function has an axis parameter, but the test raises an error for it.
There have been some discussions about this; please read this comment and a few below for more context.
@ev-br There aren't many libraries using nanobind; hence, this issue never surfaced for other libraries. Do you know any library (except MLX) that uses nanobind to expose Python functions?
Not off the top of my head, I don't know of projects using nanobind. Not sure if we need to search for those, given that you already have a simple project?
Following up on the discussion in the linked issue, let's see if I understand it right: the key issue is that nanobind-wrapped functions on "old" and "new" python versions behave differently:
on "old" pythons, inspect.signature(nanobind_wrapped_function) returns a generic Signature(*args, **kwargs),
on "new" python, it returns a useful, actual signature.
Behaves as expected by the test suite, and calling signature(func) raises a ValueError and goes straight to _test_uninspectable_func, which handles the case properly.
On the new version:
Instead of raising a ValueError, it returns a generic function signature and hence goes to _test_inspectable_func. This causes problems as the actual parameters are not identified.
With my local patch, it checks if ValueError is not raised, then whether the values are of kind Parameter.VAR_POSITIONAL and Parameter.VAR_KEYWORD, , if so, again send to _test_uninspectable_func
"old" python/nanobind raises a ValueError in inspect.signature,
"new" python/nanobind instead returns a generic Signature(*args, **kwargs),
the test expectes the "old" behavior and gives a spurious fail for the "new" behavior?
If this is correct then yes, I agree with the approach of using _test_unispectable_func if for a "generic" signature. Detecting the "generic" signature via len(params) == 2 and checking for them being VAR_POSITIONAL and VAR_KEYWORD sounds right, too --- PR welcome!
It'd be best to add a comment, too, to stress that it's working around "generic" signatures from e.g. nanobind
... and now that you're looking into test_signatures, for completeness---there are several other open issues about this test, gh-281, gh-256, gh-171. The "medium-priority" label is about right, so none of them are pressing; it's that maybe the ongoing MLX work can smoke out some specific ways they get in the way. Either way, these issues are medium-prio, and should be worked on in follow-ups to the nanobind signatures, if at all.
"old" python/nanobind raises a ValueError in inspect.signature,
"new" python/nanobind instead returns a generic Signature(*args, **kwargs),
the test expectes the "old" behavior and gives a spurious fail for the "new" behavior?
Activity
prady0t commentedon Aug 11, 2026
@ev-br There aren't many libraries using nanobind; hence, this issue never surfaced for other libraries. Do you know any library (except MLX) that uses nanobind to expose Python functions?
ev-br commentedon Aug 11, 2026
Not off the top of my head, I don't know of projects using nanobind. Not sure if we need to search for those, given that you already have a simple project?
Following up on the discussion in the linked issue, let's see if I understand it right: the key issue is that nanobind-wrapped functions on "old" and "new" python versions behave differently:
inspect.signature(nanobind_wrapped_function)returns a genericSignature(*args, **kwargs),Is this correct, or is it the other way around?
prady0t commentedon Aug 11, 2026
On the old version:
Behaves as expected by the test suite, and calling
signature(func)raises aValueErrorand goes straight to_test_uninspectable_func, which handles the case properly.On the new version:
Instead of raising a
ValueError, it returns a generic function signature and hence goes to_test_inspectable_func. This causes problems as the actual parameters are not identified.With my local patch, it checks if
ValueErroris not raised, then whether the values are of kindParameter.VAR_POSITIONALandParameter.VAR_KEYWORD,, if so, again send to_test_uninspectable_funcev-br commentedon Aug 12, 2026
Okay, so is the following correct:
inspect.signature,Signature(*args, **kwargs),If this is correct then yes, I agree with the approach of using
_test_unispectable_funcif for a "generic" signature. Detecting the "generic" signature vialen(params) == 2and checking for them being VAR_POSITIONAL and VAR_KEYWORD sounds right, too --- PR welcome!It'd be best to add a comment, too, to stress that it's working around "generic" signatures from e.g.
nanobindev-br commentedon Aug 12, 2026
... and now that you're looking into
test_signatures, for completeness---there are several other open issues about this test, gh-281, gh-256, gh-171. The "medium-priority" label is about right, so none of them are pressing; it's that maybe the ongoing MLX work can smoke out some specific ways they get in the way. Either way, these issues are medium-prio, and should be worked on in follow-ups to the nanobind signatures, if at all.prady0t commentedon Aug 12, 2026
Precisely!
Let me open a PR.