You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This (simplified) code generates a warning: Returning Any from function declared to return "_SelfType" (for context, this code implements a base class similar to namedtuple but using regular classes instead of tuple):
class PlainOldData:
__slots__ = () # type: Sequence[str]
_SelfType = TypeVar('_SelfType', bound='PlainOldData')
def _replace(self: _SelfType, **kwargs: Dict[Text, Any]) -> _SelfType: # pylint: disable=undefined-variable
"""Make a new object, replacing fields with new values."""
new_attrs = {
k: kwargs.pop(k) if k in kwargs else getattr(self, k)
for k in self.__slots__
}
if kwargs:
raise ValueError('Unknown field names: {!r}'.format(list(kwargs)))
return self.__class__(**new_attrs)
When I change the return statement to return cast(self._SelfType, self.__class__(**new_attrs)), I get Redundant cast to self._SelfType?
(There's a copy&paste error in my example: _SelfType is indented incorrectly; it also needs a line: from typing import Any, Dict, Sequence, Text, TypeVar, cast):
With the returncast, mypy generates two messages:
/tmp/xx.py:18: note: Redundant cast to self._SelfType?
/tmp/xx.py:18: error: Invalid type "self"
The problem seems to be with type of self.__class__ not being precise. I remember discussing this same issue some time ago but I can't find an open issue. It's unclear if this should be fixed in typeshed or in mypy.
Any
This suggest that mypy isn't smart enough when inferring the type of self.__class__. I think the root cause is that it just takes the declaration of __class__ from typeshed rather than understanding that it returns something akin to Type[<the current class>]. (Barring __class__ assignment.) And maybe the type constraint on self, if there is one, should also be taken into account.
If you feel like it, see if you can make a PR about this!
We actually tried to fix this in typeshed before (python/typeshed#1549) but had to revert because it exposed problems in internal Dropbox codebases. @gvanrossum maybe we should try that typeshed fix again?
Activity
kamahen commentedon Feb 20, 2018
(There's a copy&paste error in my example: _SelfType is indented incorrectly; it also needs a line:
from typing import Any, Dict, Sequence, Text, TypeVar, cast):With the
returncast, mypy generates two messages:JukkaL commentedon Feb 20, 2018
Here's a simplified repro (run using
mypy --warn-return-any):The problem seems to be with type of
self.__class__not being precise. I remember discussing this same issue some time ago but I can't find an open issue. It's unclear if this should be fixed in typeshed or in mypy.gvanrossum commentedon Feb 20, 2018
Breaking this out as
The types are revealed to be, respectively,
builtins.typeAnyThis suggest that mypy isn't smart enough when inferring the type of
self.__class__. I think the root cause is that it just takes the declaration of__class__from typeshed rather than understanding that it returns something akin toType[<the current class>]. (Barring__class__assignment.) And maybe the type constraint onself, if there is one, should also be taken into account.If you feel like it, see if you can make a PR about this!
kamahen commentedon Feb 20, 2018
Guido: whom are you referring to by "you" in "see if you can make a PR about this"?
JukkaL commentedon Feb 20, 2018
Using
return type(self)(...)works for me as a workaround.JukkaL commentedon Feb 20, 2018
Marking as high priority since
self.__class__seems to be used all over the place in internal Dropbox codebases at least.kamahen commentedon Feb 20, 2018
(I made an error for
kwargs; the function definition should be)
[Note to self: re-read PEP 484 before posting any issues]
JelleZijlstra commentedon Feb 20, 2018
We actually tried to fix this in typeshed before (python/typeshed#1549) but had to revert because it exposed problems in internal Dropbox codebases. @gvanrossum maybe we should try that typeshed fix again?
gvanrossum commentedon Feb 21, 2018