Open DetachHead opened 2 years ago
also no error when there's no second argument:
class A:
@property
def foo(self) -> int:
...
@foo.setter
def foo(self) -> None: # no mypy error
...
a = A()
a.foo = 1 # runtime error - TypeError: A.foo() takes 1 positional argument but 2 were given
and also no error when the setter type is different to the getter type
class Foo:
@property
def foo(self) -> int:
...
@foo.setter
def foo(self, value: str) -> None:
...
however you get an error when attempting to use the setter:
f = Foo()
f.foo = "" # Incompatible types in assignment (expression has type "str", variable has type "int")
Similar example:
class A:
def init(self) -> None:
self._a: int | None = None
@property
def a(self) -> int:
if self._a is None:
raise ValueError
return self._a
@a.setter
def a(self, val: int | None) -> None:
self._a = val
a = A()
a.a = None # Incompatible types in assignment (expression has type "None", variable has type "int") [assignment]
In my scenario I would like it to work like this but if it is bad practice that the setter allows different types than the getter it should warn in the definition of the setter…
I would argue that it is not necessarily a problem in itself. We can use this to implement a "smart setter" that takes as type to build on this example Union[int, str]
, and tries to convert a str
to an int
.
What I see as a problem is rather that when you then try to set foo
in a way compatible with the declaration and implementation (ie. assign a string to it), then despite the code being correct, mypy
will ignore the type declared in the setter, and validate against the getter type instead - see https://github.com/python/mypy/issues/3004 where the consensus is that this is a valid use case.
Maybe close this ticket?
Even if #3004 gets implemented, there are still several examples here of invalid setters that should be errors (incorrect number of arguments) so I'm leaving this issue open regardless
https://mypy-play.net/?mypy=latest&python=3.10&flags=show-error-context%2Cshow-error-codes%2Cstrict%2Ccheck-untyped-defs%2Cdisallow-any-decorated%2Cdisallow-any-expr%2Cdisallow-any-explicit%2Cdisallow-any-generics%2Cdisallow-any-unimported%2Cdisallow-incomplete-defs%2Cdisallow-subclassing-any%2Cdisallow-untyped-calls%2Cdisallow-untyped-decorators%2Cdisallow-untyped-defs%2Cno-implicit-optional%2Cno-implicit-reexport%2Clocal-partial-types%2Cstrict-equality%2Cwarn-incomplete-stub%2Cwarn-redundant-casts%2Cwarn-return-any%2Cwarn-unreachable%2Cwarn-unused-configs%2Cwarn-unused-ignores&gist=3a081cf4b94705271106cf081232887f