I'm extending a class from a library (class A
) that has a very long list of arguments (shortened here for readability). To avoid duplicating the entire base class __init__
signature in my class I am using *args
and **kwargs
, however this erases the base class type information, making it more difficult to use my class downstream.
class A:
def __init__(self, a: int, b: str, c: float = 3.14, d: bool = False):
# Library Initialization Logic
pass
class B(A):
def __init__(self, *args, **kwargs):
# Supplemental Initialization Logic
super().__init__(*args, **kwargs)
In the past I have used and ParamSpec
to annotate function decorators which use *args
and **kwargs
with P.args
and P.kwargs
, however PEP 612 does not seem applicable to this situation, so while the following is an acceptable use of ParamSpec
:
T = TypeVar('T')
P = ParamSpec('P')
def example(function: Callable[P, T]) -> Callable[P, T]:
def decorator(*args: P.args, **kwargs: P.kwargs) -> T:
# Logic here
return function(*args, **kwargs)
return decorator
This is not, with Pylance producing the error ParamSpec "P" has no meaning in this context
, and MyPy producing general errors about incompatible types. This makes sense, as there is nothing linking type information from class A
's initializer to P
.
P = ParamSpec('P')
class B(A):
def __init__(self, *args: P.args, **kwargs: P.kwargs):
# Supplemental Initialization Logic
super().__init__(*args, **kwargs)
Is there any way to automatically copy the typing information in this situation without manually recreating the function signature?