Deprecated overloaded property setters

For the following snippet:

from typing import overload
from warnings import deprecated

class A:
    @property
    def t1(self) -> int:
        ...

    @t1.setter
    @deprecated("Setting t is deprecated")
    def t1(self, value: int) -> None:
        ...

    @property
    def t2(self) -> int:
        ...

    @t2.setter
    @overload
    @deprecated("Setting t to None is deprecated")
    def t2(self, value: None) -> None:
        ...

    @t2.setter
    @overload
    def t2(self, value: int) -> None:
        ...

    @t2.setter
    def t2(self, value: int | None) -> None:
        ...

a = A()

a.t1 = 1
a.t2 = None

Only Pyright and Mypy error on the t1 setter. Only Pyrefly report the error on the t2 setter when setting to None (although it also reports a weird error on the second overload definition of t2).

Playgrounds: Pyright, Mypy, Pyrefly, ty.

Is this something that is expected to work? Should it be incorporated to the spec, or should I open issues for each type checker directly?

2 Likes

I agree this should work as you expect, and you should report issues to type checkers about it.

5 Likes

I think we’d definitely like this to work in ty eventually. A lot of the more “advanced” parts of deprecated support are still WIP for ty

2 Likes

Pyright issue: Support `@deprecated` on overloaded property setters · Issue #11478 · microsoft/pyright · GitHub
Mypy issue: Support `@deprecated` on overloaded property setters · Issue #21593 · python/mypy · GitHub
Pyrefly issue: Overloaded property setter reported as deprecated · Issue #3701 · facebook/pyrefly · GitHub
ty issue comment: Implement `@warnings.deprecated` checking for dunder methods and properties · Issue #843 · astral-sh/ty · GitHub

1 Like