-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
disallow A().__class__ = B
#12997
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The reason mypy reports an error, is because mypy doesn't support asymmetric properties, it will only use the annotation from the getter, so mypy already works the way you want it to by accident. I agree however that it seems better to only allow If you want to do an unsafe assignment you can still do it, you'll just have to ignore the type error. |
Perhaps this could also explain why this hasn't been brought up before (as far as I could tell) 🤔 |
An exploratory PR couldn't hurt. To me, changing the setter types seems fine. |
the mypy primer seems to like it |
As Daverball mentions, mypy doesn't model setters of properties correctly, so it already works the way you want it to so primer is a no-op |
Does that mypy bug also apply to inheritance, |
Yes, also I wouldn't call it a bug per se, it's a difference between mypy's type model and python's object model of properties. I assume this was originally an intentional design choice, so mypyc can always optimize properties a certain way. |
The
object.__class__
getter is annotated to returntype[Self]
, while the setter accepts any argument that's assignableobject
.typeshed/stdlib/builtins.pyi
Lines 107 to 110 in 300204c
As I also mentioned in microsoft/pyright#9410 (comment), this could lead to type-unsafe situation, e.g.
Pyright accepts this, as you'd expect by looking at the stubs (playground link).
However, mypy reports an error reports an error at
a.__class__ = B
(playground link), so I'm guessing it special-cased it.At runtime the
__class__
behaves just like any other attribute, i.e. invariantly, when getting/setting.So that's why I think that
object.__class__
should be more "self-centered", and only accepttype[Self]
in its setter.As for a practical use-case; I recently came up with the following trick. But at the moment, this unexpectedly requires adding
# type: ignore
s with both pyright and mypy:playgrounds:
The text was updated successfully, but these errors were encountered: