Skip to content

Commit

Permalink
Improve error message for implicitly abstract functions (#13776)
Browse files Browse the repository at this point in the history
Fixes #13770
  • Loading branch information
hauntsaninja committed Sep 30, 2022
1 parent a1eeddb commit 7819085
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 6 deletions.
9 changes: 5 additions & 4 deletions mypy/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -1341,15 +1341,16 @@ def cannot_instantiate_abstract_class(
return
if len(attrs_with_none) == 1:
note = (
"The following method was marked implicitly abstract because it has an empty "
"function body: {}. If it is not meant to be abstract, explicitly return None."
f"{attrs_with_none[0]} is implicitly abstract because it has an empty function "
"body. If it is not meant to be abstract, explicitly `return` or `return None`."
)
else:
note = (
"The following methods were marked implicitly abstract because they have empty "
"function bodies: {}. If they are not meant to be abstract, explicitly return None."
f"function bodies: {format_string_list(attrs_with_none)}. "
"If they are not meant to be abstract, explicitly `return` or `return None`."
)
self.note(note.format(format_string_list(attrs_with_none)), context, code=codes.ABSTRACT)
self.note(note, context, code=codes.ABSTRACT)

def base_class_definitions_incompatible(
self, name: str, base1: TypeInfo, base2: TypeInfo, context: Context
Expand Down
4 changes: 2 additions & 2 deletions test-data/unit/check-protocols.test
Original file line number Diff line number Diff line change
Expand Up @@ -3105,14 +3105,14 @@ class NoneCompatible(Protocol):

class A(NoneCompatible): ...
A() # E: Cannot instantiate abstract class "A" with abstract attributes "f", "g", "h", "i" and "j" \
# N: The following methods were marked implicitly abstract because they have empty function bodies: "f", "g", "h", "i" and "j". If they are not meant to be abstract, explicitly return None.
# N: The following methods were marked implicitly abstract because they have empty function bodies: "f", "g", "h", "i" and "j". If they are not meant to be abstract, explicitly `return` or `return None`.

class NoneCompatible2(Protocol):
def f(self, x: int): ...

class B(NoneCompatible2): ...
B() # E: Cannot instantiate abstract class "B" with abstract attribute "f" \
# N: The following method was marked implicitly abstract because it has an empty function body: "f". If it is not meant to be abstract, explicitly return None.
# N: "f" is implicitly abstract because it has an empty function body. If it is not meant to be abstract, explicitly `return` or `return None`.

class NoneCompatible3(Protocol):
@abstractmethod
Expand Down

0 comments on commit 7819085

Please sign in to comment.