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
{{ message }}
Repository navigation
False positive safe-super errors for properties defined in protocol classes using inheritance #14757
Empty properties defined in a protocol class that is subclassed by another protocol are incorrectly classified by mypy as abstract methods - this can then result in a safe-super error if the parent property is accessed via super() within a class that is type hinted with the child protocol, e.g. when type hinting self in mixin classes (as described here).
To Reproduce
from __future__ importannotationsfromtypingimportProtocol, Optional, NoReturnclassDataset(Protocol):
defvalidate(self) ->Optional[NoReturn]:
...
@propertydefhas_schema(self) ->bool:
...
classTSDataset(Dataset, Protocol):
@propertydefnum_rows(self) ->int:
...
classTSDatasetMixin:
defcheck_schema(self: TSDataset) ->None:
super().validate()
ifsuper().has_schema:
print('Dataset has a schema')
Expected Behavior
No errors.
Actual Behavior
mypy_safe_super_protocol.py:24: error: Call to abstract method "has_schema" of "Dataset" with trivial body via super() is unsafe [safe-super]
Found 1 error in 1 file (checked 1 source file)
Your Environment
Mypy version used: 1.0.1
Mypy command-line flags: None
Mypy configuration options from mypy.ini (and other config files): None
I also want to add that this also happens even if we directly call a protocol's method in a class that inherits from that protocol..
Here's an example that produces the same problem:
_my_protocol.py
from typing import Protocol
class MyProtocol(Protocol):
def my_method(self) -> dict[str, int | str]:
...
my_mixin.py
from typing import TYPE_CHECKING
from ._my_protocol import MyProtocol
if TYPE_CHECKING:
_Base = MyProtocol
else:
_Base = object
class MyMixin(_Base):
def my_method(self) -> dict[str, int | str]:
return super().my_method()
Error: error: Call to abstract method "my_method" of "MyProtocol" with trivial body via super() is unsafe [safe-super]
Hi @ebram96 - I think mypy is correct in this case. Your MyMixin class is a regular class and not a Protocol class (as it does not explicitly inherit from Protocol itself) and since MyProtocol does not provide an implementation of my_method, mypy is correct to raise a safe-super error for the super().my_method() call. PEP544 gives a similar example of a safe-super error for the BadColor class.
I have a variant of this error for a mixin class using super() against a protocol:
fromtypingimportProtocolclassBaseClassProtocol(Protocol):
defsome_method(self) ->str|None: ...
classSubClassProtocol(BaseClassProtocol, Protocol):
@propertydefsome_flag(self) ->str: ...
classMyMixin:
defsome_method(self: SubClassProtocol) ->str|None:
ifself.some_flag: # `self` type is defined to access thisreturn'some_flag'returnsuper().some_method() # But this is flagged for `safe_super`
The fix from #12344 / #14082 doesn't work to stop the safe_super error, but replacing the method definition with Callable type makes the error go away:
Activity
paperclipstudio commentedon Feb 24, 2023
I think I might be able to add to this
with this code
We get
Which I believe should both be the
builtins.strmypy is not picking up the Level1_2 (I think alway the last class that inherits from Interface) methodnph commentedon Feb 24, 2023
Thanks @paperclipstudio. I believe mypy is actually correct here. The expression:
will call
methodinLevel1_2- hence the revealed type ofstr. Whereas the expression:will call
methodinInterface.paperclipstudio commentedon Feb 27, 2023
Yes, Sorry my mistake, thanks for the help.
ebram96 commentedon Nov 8, 2023
I also want to add that this also happens even if we directly call a protocol's method in a class that inherits from that protocol..
Here's an example that produces the same problem:
_my_protocol.py
my_mixin.py
Error:
error: Call to abstract method "my_method" of "MyProtocol" with trivial body via super() is unsafe [safe-super]nph commentedon Nov 9, 2023
Hi @ebram96 - I think mypy is correct in this case. Your
MyMixinclass is a regular class and not a Protocol class (as it does not explicitly inherit fromProtocolitself) and sinceMyProtocoldoes not provide an implementation ofmy_method, mypy is correct to raise asafe-supererror for thesuper().my_method()call. PEP544 gives a similar example of asafe-supererror for theBadColorclass.jace commentedon Jun 28, 2024
I have a variant of this error for a mixin class using
super()against a protocol:Playground URL: https://mypy-play.net/?mypy=latest&python=3.12&gist=7129a6792261d89c8e3b414a6f12e0f8
jace commentedon Jun 28, 2024
The fix from #12344 / #14082 doesn't work to stop the
safe_supererror, but replacing the method definition withCallabletype makes the error go away:Satisfy mypy 1.11.1