For writing a wrapper around an existing function, I want to that wrapper to have the same, or very similar, type.
For example:
import os
def my_open(*args, **kwargs):
return os.open(*args, **kwargs)
Tye type signature for os.open() is complex and may change over time as its functionality and typings evolve, so I do not want to copy-paste the type signature of os.open() into my code. Instead, I want to infer the type for my_open(), so that it "copies" the type of os.open()'s parameters and return values.
my_open() shall have the same type as the wrapped function os.open().
I would like to do the same thing with a decorated function:
@contextmanager
def scoped_open(*args, **kwargs):
"""Like `os.open`, but as a `contextmanager` yielding the FD.
"""
fd = os.open(*args, **kwargs)
try:
yield fd
finally:
os.close(fd)
Here, the inferred function arguments of scoped_open() shall be the same ones as os.open(), but the return type shall be a Generator of the inferred return type of os.open() (currently int, but again I do not wish to copy-paste that int).
I read some things about PEP 612 here:
These seem related, but the examples given there still always copy-paste at least some part of the types.
How can this be done in pyright/mypy/general?
You could simply pass [the function you want to copy the signature of] into [a decorator factory] which produces a no-op decorator that affects the typing API of the decorated function.
The following example can be checked on pyright-play.net (requires Python >= 3.12, as it uses syntax from PEP 695).