0

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?

0 Answers0