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