-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Self
type isn't considered to be the same as the explicit class type
#16558
Comments
I believe this is a duplicate of #14075 |
I don't think this is the same as #14075. I also don't think this is a bug. Mypy is doing the right thing here.
Consider the following code: class Parent:
def method1(self) -> Self:
return Parent() # This is a type violation
class Child(Parent):
pass
Child().method1() # This should return an instance of Child For details, refer to PEP 673. Here's the corrected code sample that type checks without error: from enum import Enum, auto
class Dir(Enum):
LEFT = auto()
UP = auto()
RIGHT = auto()
DOWN = auto()
def opposed(self) -> "Dir":
match self:
case Dir.LEFT:
return Dir.RIGHT
case Dir.UP:
return Dir.DOWN
case Dir.RIGHT:
return Dir.LEFT
case Dir.DOWN:
return Dir.UP |
Right, it's not the same thing as #14075, and I see the point you're making @erictraut. I think it would be reasonable for type checkers to exclude final classes (including enums with members) from this kind of check, however. No subclass of |
I will say, I forgot about putting the type in a string 😅 |
IMO that would require a change to the typing spec, and I'm not convinced it would be a good change. I think it would be better (both more correct from a typing standpoint and clearer in the code) to use the class itself in the annotation rather than @AlexWaygood, if you feel strongly about this, please raise it in the typing forums to see if others think that exemptions should be added to |
I've found inconsistencies in the way Self is handled between Pyright and Mypy (reported in #16554). PEP 673 doesn't cover both the scenarios I've found (decorator and unbound method). Mypy gets it wrong in the first, Pyright in the second. |
I generally agree with Eric here. Although I do find the following related example interesting. mypy will complain about the second one being able to return None, but not the first. This is something that mypy should fix, and will be important if we make the change in #14075. (pyright complains about neither, presumably because it's being cleverer about enum finality)
|
I am not sure if this is the appropriate
topic-self-types
from typing import Self
class Point:
def __init__(self, x: float, y: float) -> None:
self._x = x
self._y = y
def copy(self: Self) -> Self:
p = Point(self._x, self._y)
return p # This fails mypy (1.11.2) tells me self-type.py:9: error: Incompatible return value type (got "Point", expected "Self") [return-value] I will leave it to others who have a far better understanding than I do of what |
@jpgoldberg, the code in your code sample is a type violation, and mypy is correct to report this as an error. The type of class Point:
...
def copy[S: Point](self: S) -> S:
p = Point(self._x, self._y)
return p # Type violation |
@jpgoldberg Mypy is correct to reject that code, see #16558 (comment) above. The issue is that class Point:
# ...
def copy(self: Self) -> Self:
p = type(self)(self._x, self._y)
return p |
Thank you @brianschubert!
I had at one point attempted |
Bug Report
In methods where the
Self
type (fromtyping
) is used, theSelf
type from is considered as distinct to the actual self type (say,Foo
). This is the cause of a multitude of issues.To exemplify these issues, I will use
enum.Enum
s. as they have a clear reason to need access to the runtime self type.In a method returning
Self
, one may not returnFoo.Variant
, receiving an error along the lines of:To work around this, one must use
typing.cast
or# type: ignore
comments.Furthermore, within those same methods returning
Self
, theself
parameter auto-magically assumes the type ofSelf
, to accommodate the fact thatSelf
is seen by mypy as aTypeVar
and "A function returning TypeVar should receive at least one argument containing the same TypeVar [type-var]".This brings on the unfortunate consequence that one cannot match the
self
value against its own enum variants exhaustively, mypy simply refuses to acknowledge thatself
may take on values ofFoo.Variant
. Trying to access the fields through the self parameter asself.Variant
reveals that it indeed has the typeauto
(or whichever value was assigned to it), rather than the literal or the class.To Reproduce
https://mypy-play.net/?mypy=latest&python=3.11&flags=strict&gist=808ead69249e64d6929a55149b0a3f1c
Actual Behavior
For the above example, the errors include:
Environment
1.8.0+dev.5b1a231425ac807b7118aac6a68b633949412a36
)--strict
mypy.ini
(and other config files):strict = True
3.11.5
The text was updated successfully, but these errors were encountered: