Skip to content

Incorrect overload parameter mismatch when typing decorator #11333

@max-kamps

Description

@max-kamps

Describe the bug
Trying to type a decorator, and I'm running into some seemingly spurious errors. I've tried to figure out what exactly causes this, to no avail.

The goal is to have the an optional cls parameter, and to have the return type vary based on whether it is present or absent. Mypy accepts the following code, but Pyright does not.

Apologies if this has already been reported, but I couldn't find any existing issue.

**Code **

Pyright playground

Mypy playground

from typing import overload, Callable

@overload
def decorator[T](cls: type[T], /, *, extra: int = 0) -> type[T]:
    ...

@overload
def decorator[T](cls: None = None, /, *, extra: int = 0) -> Callable[[type[T]], type[T]]:
    ...

def decorator[T](cls: type[T] | None = None, /, *, extra: int = 0):
    if cls is None:
        def wrapper(cls: type[T]) -> type[T]:
            return decorator(cls, extra=extra)
        return wrapper
    
    setattr(cls, "__extra__", extra)
    return cls

Pyright error message:

Overloaded implementation is not consistent with signature of overload 2
  Function return type "(type[T@decorator]) -> type[T@decorator]" is incompatible with type "((cls: type[T@decorator]) -> type[T@decorator]) | type[T@decorator]"
    Type "(type[T@decorator]) -> type[T@decorator]" is not assignable to type "((cls: type[T@decorator]) -> type[T@decorator]) | type[T@decorator]"
      Type "(type[T@decorator]) -> type[T@decorator]" is not assignable to type "type[T@decorator]"
      Type "(type[T@decorator]) -> type[T@decorator]" is not assignable to type "(cls: type[T@decorator]) -> type[T@decorator]"
        Missing keyword parameter "cls"
          Position-only parameter mismatch; parameter "cls" is not position-only
          Position-only parameter mismatch; expected 1 but received 0  (reportInconsistentOverload)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions