[Python] Why does Pyright report an incompatible method override when using a decorator with...

Discussão em 'Python' iniciado por Stack, Junho 16, 2025.

  1. Stack

    Stack Membro Participativo

    I'm experiencing a type checking error with Pyright when using a decorator with a method that overrides another method. The error occurs when the method has two parameters (self and another parameter), but disappears when there's only one parameter (self)

    Here`s my code:

    # With Error
    from functools import wraps
    from typing import Callable, Concatenate, ParamSpec, TypeVar

    T = TypeVar("T")
    P = ParamSpec("P")
    R = TypeVar("R")


    def use_channel(
    func: Callable[Concatenate[T, str, P], R]
    ) -> Callable[Concatenate[T, str, P], R]:
    @wraps(func)
    def wrapper(self: T, channel: str, *args: P.args, **kwargs: P.kwargs) -> R:
    print(f"[Decorator] self={self}, channel={channel}")
    return func(self, channel, *args, **kwargs)
    return wrapper


    class A:
    def set_channel(self, channel: str):
    pass


    class B(A):
    @use_channel
    # It result in Pyright Error
    def set_channel(self, channel: str):
    pass


    # No Error
    from functools import wraps
    from typing import Callable, Concatenate, ParamSpec, TypeVar

    T = TypeVar("T")
    P = ParamSpec("P")
    R = TypeVar("R")


    def use_channel(
    func: Callable[Concatenate[T, P], R]
    ) -> Callable[Concatenate[T, P], R]:
    @wraps(func)
    def wrapper(self: T, *args: P.args, **kwargs: P.kwargs) -> R:
    print(f"[Decorator] self={self}")
    return func(self, *args, **kwargs)
    return wrapper


    class A:
    def set_channel(self, channel: str):
    pass


    class B(A):
    @use_channel
    # No Error
    def set_channel(self, channel: str):
    pass


    The error message is:


    Method "set_channel" overrides class "A" in an incompatible manner

    Parameter 2 mismatch: base parameter "channel" is keyword parameter, override parameter is position-only
    ​

    Can someone explain why having one or two parameters makes a difference here? Is this related to how Pyright checks compatibility between methods?"

    Continue reading...

Compartilhe esta Página