Skip to content

ENH: infer nin/nout for frompyfunc#30670

Open
danielzgtg wants to merge 3 commits intonumpy:mainfrom
danielzgtg:feat/frompyfuncInferCoargcount
Open

ENH: infer nin/nout for frompyfunc#30670
danielzgtg wants to merge 3 commits intonumpy:mainfrom
danielzgtg:feat/frompyfuncInferCoargcount

Conversation

@danielzgtg
Copy link
Copy Markdown
Contributor

This eliminates redundantly typing nin/nout especially when obvious with lambda.

Before

home@daniel-desktop3:~$ python3
Python 3.13.7 (main, Nov 24 2025, 20:51:28) [GCC 15.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> np.frompyfunc(lambda x: x, 1, 1).nin
1
>>> np.frompyfunc(lambda x: x, 1, 1).nout
1
>>> np.frompyfunc(lambda x: x + y, 2, 1).nin
2
>>> np.frompyfunc(lambda x: x + y, 2, 1).nout
1
>>> np.frompyfunc(lambda x: x)
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    np.frompyfunc(lambda x: x)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^
TypeError: frompyfunc() missing required argument 'nin' (pos 2)
>>> np.frompyfunc(lambda x, y: x + y)
Traceback (most recent call last):
  File "<python-input-2>", line 1, in <module>
    np.frompyfunc(lambda x, y: x + y)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
TypeError: frompyfunc() missing required argument 'nin' (pos 2)
>>> 

After

(venv) home@daniel-desktop3:~/CLionProjects/numpy$ spin python
Invoking `build` prior to invoking Python:
$ /home/home/CLionProjects/numpy/venv/bin/python3 vendored-meson/meson/meson.py compile -C build
INFO: autodetecting backend as ninja
INFO: calculating backend command to run: /home/home/CLionProjects/numpy/venv/bin/ninja -C /home/home/CLionProjects/numpy/build
ninja: Entering directory `/home/home/CLionProjects/numpy/build'
[1/1] Generating numpy/generate-version with a custom command
Saving version to numpy/version.py
$ /home/home/CLionProjects/numpy/venv/bin/python3 vendored-meson/meson/meson.py install --only-changed -C build --destdir ../build-install
$ export PYTHONPATH="/home/home/CLionProjects/numpy/build-install/usr/lib/python3/dist-packages"
🐍 Launching Python with PYTHONPATH="/home/home/CLionProjects/numpy/build-install/usr/lib/python3/dist-packages"
$ /home/home/CLionProjects/numpy/venv/bin/python3 -P
Python 3.13.7 (main, Nov 24 2025, 20:51:28) [GCC 15.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> np.frompyfunc(lambda x: x).nin
1
>>> np.frompyfunc(lambda x: x).nout
1
>>> np.frompyfunc(lambda x, y: x + y).nin
2
>>> np.frompyfunc(lambda x, y: x + y).nout
1
>>> 

Copy link
Copy Markdown
Member

@jorenham jorenham left a comment

Choose a reason for hiding this comment

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

Thanks; sounds like a good improvement to me (assuming that it works).

This will need runtime test, e.g. to verify that non-function callables like

class F:
    def __call__(self, x):
        return x

assert np.frompyfunc(F(), 1, 1)(42) == 42

still work.

@danielzgtg danielzgtg force-pushed the feat/frompyfuncInferCoargcount branch 2 times, most recently from c1cea0d to 003b2cc Compare January 19, 2026 13:31
@jorenham
Copy link
Copy Markdown
Member

The docstring signatures also need to be updated

add_newdoc('numpy._core.umath', 'frompyfunc',
"""
frompyfunc(func, /, nin, nout, **kwargs)
--
frompyfunc(func, /, nin, nout, *[, identity])

That'll (magically) also fix the stubtest errors :)

@danielzgtg danielzgtg force-pushed the feat/frompyfuncInferCoargcount branch 2 times, most recently from d9cd8c5 to cab0c24 Compare January 19, 2026 14:27
Copy link
Copy Markdown
Member

@jorenham jorenham left a comment

Choose a reason for hiding this comment

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

Ok, all good from me on the typing side. It might be good for another maintainer to look at this before merging though.

@danielzgtg danielzgtg force-pushed the feat/frompyfuncInferCoargcount branch 4 times, most recently from 2cca835 to bf204db Compare January 20, 2026 12:58
@danielzgtg danielzgtg requested a review from seberg January 21, 2026 15:29
@danielzgtg danielzgtg force-pushed the feat/frompyfuncInferCoargcount branch 2 times, most recently from 09338f3 to d8b9292 Compare January 22, 2026 11:49
@danielzgtg danielzgtg force-pushed the feat/frompyfuncInferCoargcount branch 2 times, most recently from 6cd37f6 to 4494eb4 Compare January 22, 2026 14:34
Co-authored-by: Joren Hammudoglu <jhammudoglu@gmail.com>
@danielzgtg danielzgtg force-pushed the feat/frompyfuncInferCoargcount branch from 4494eb4 to 2f9de76 Compare January 22, 2026 15:54
@mattip
Copy link
Copy Markdown
Member

mattip commented Jan 26, 2026

Seems to be a net positive. Do we have any idea how this might break current usage? Trying to prevent a regression like #24530

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.

4 participants