Skip to content

BUG: test_func_signature gives false failures on certain Python versions for nanobind-bound functions #449

Closed

Description

@prady0t

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.

Activity

  1. prady0t commented on Aug 11, 2026

    @prady0t
    ContributorAuthor

    @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?

  2. ev-br commented on Aug 11, 2026

    @ev-br
    Member

    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.

    Is this correct, or is it the other way around?

  3. prady0t commented on Aug 11, 2026

    @prady0t
    ContributorAuthor

    On the old version:

    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

  4. ev-br commented on Aug 12, 2026

    @ev-br
    Member

    Okay, so is the following correct:

    • "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

  5. ev-br commented on Aug 12, 2026

    @ev-br
    Member

    ... 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.

  6. prady0t commented on Aug 12, 2026

    @prady0t
    ContributorAuthor

    "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?

    Precisely!

    Let me open a PR.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions