Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@jorenham
Copy link
Member

@jorenham jorenham commented Nov 14, 2025

This adds a dynamic __signature__ attribute to the individual ufuncs, which gets used by introspection tools like inspect.signature.

tp_getattro is used in order to avoid ufunc.__signature__ from becoming a class attribute, which sphinx did not seem to like.

Before, IPython showed something like this for np.exp?:

Signature:       np.exp(*args, **kwargs)
Type:            ufunc
String form:     <ufunc 'exp'>   
[...]

After this change, this is what it looks like:

Signature:      
np.exp(
    x,
    /,
    out=None,
    *,
    where=True,
    casting='same_kind',
    order='K',
    dtype=None,
    subok=True,
    signature=None,
)
Call signature:  np.exp(*args, **kwargs)
Type:            ufunc
String form:     <ufunc 'exp'>     
[...]

The "call signature" refers to np.ufunc.__call__.__text_signature__, which remains unchanged.

In case of divmod, the signature is

np.divmod(
    x1,
    x2,
    /,
    out=(None, None),
    *,
    where=True,
    casting='same_kind',
    order='K',
    dtype=None,
    subok=True,
    signature=None,
)

GUFuncs include **kwargs, because it's not known whether they have an axis parameter:

np.vecdot(
    x1,
    x2,
    /,
    out=None,
    *,
    casting='same_kind',
    order='K',
    dtype=None,
    subok=True,
    signature=None,
    **kwargs,
)

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! Main comment is about being explicit for gufuncs as well.

Also, as I was looking at https://numpy.org/doc/stable/reference/ufuncs.html to remind myself of the actual signatures, I saw that the text mentions __doc__ - do you want to mention __signature__ there as well? It does look like that list is complete, so might as well keep it like that!

Separately, currently np.add.reduce? just shows the docstring, so all fine from a user perspective. But does it work for introspection? If so, definitely for another PR, but I thought I'd mention it in part in case it has implications here, that really the __signature__ should somehow be attached to __call__ rather than the ufunc itself.

@charris

This comment was marked as resolved.

@jorenham
Copy link
Member Author

Separately, currently np.add.reduce? just shows the docstring, so all fine from a user perspective.

That even seems necessary, judging by the circleCI errors; I'll take of care of it.

I'd mention it in part in case it has implications here, that really the __signature__ should somehow be attached to __call__ rather than the ufunc itself.

That's initially what I had planned on doing. But that'd require a separate signature per ufunc instance, whereas for the other methods a one-size-fits-all signature is used. The C machinery surrounding __call__ was also quite different from the other methods. So I wasn't able to figure out how I'd be able to attach a specializing __text_signature__ or __signature__ to ufunc.__call__. That's why I ended up settling for ufunc.__signature__, because that's what inspect.signature will also support.

@jorenham jorenham force-pushed the specialized-ufunc-runtime-signatures branch from f058983 to eff475c Compare November 14, 2025 23:02
@jorenham jorenham force-pushed the specialized-ufunc-runtime-signatures branch from 663b253 to 968636a Compare November 15, 2025 00:17
@jorenham jorenham requested a review from mhvk November 15, 2025 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants