Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mypy/checkmember.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@ def validate_super_call(node: FuncBase, mx: MemberContext) -> None:
if node.impl:
impl = node.impl if isinstance(node.impl, FuncDef) else node.impl.func
unsafe_super = impl.is_trivial_body
elif not node.is_property and node.items:
assert isinstance(node.items[0], Decorator)
unsafe_super = node.items[0].func.is_trivial_body
if unsafe_super:
mx.msg.unsafe_super(node.name, node.info.name, mx.context)

Expand Down
9 changes: 8 additions & 1 deletion mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1461,8 +1461,15 @@ def handle_missing_overload_implementation(self, defn: OverloadedFuncDef) -> Non
item.func.abstract_status = IS_ABSTRACT
else:
item.abstract_status = IS_ABSTRACT
elif all(
isinstance(item, Decorator) and item.func.abstract_status == IS_ABSTRACT
for item in defn.items
):
# Since there is no implementation, it can't be called via super().
if defn.items:
assert isinstance(defn.items[0], Decorator)
defn.items[0].func.is_trivial_body = True
else:
# TODO: also allow omitting an implementation for abstract methods in ABCs?
self.fail(
"An overloaded function outside a stub file must have an implementation",
defn,
Expand Down
8 changes: 6 additions & 2 deletions mypyc/irbuild/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,12 @@ def prepare_methods_and_attributes(

# Handle case for regular function overload
else:
assert node.node.impl
prepare_method_def(ir, module_name, cdef, mapper, node.node.impl, options)
if not node.node.impl:
errors.error(
"Overloads without implementation are not supported", path, cdef.line
)
else:
prepare_method_def(ir, module_name, cdef, mapper, node.node.impl, options)

if ir.builtin_base:
ir.attributes.clear()
Expand Down
25 changes: 25 additions & 0 deletions test-data/unit/check-functions.test
Original file line number Diff line number Diff line change
Expand Up @@ -3541,3 +3541,28 @@ def f(x: Callable[[Arg(int, 'x')], None]) -> None: pass
y: Callable[[Union[int, str]], None]
f(y) # E: Argument 1 to "f" has incompatible type "Callable[[Union[int, str]], None]"; expected "Callable[[Arg(int, 'x')], None]"
[builtins fixtures/tuple.pyi]

[case testAbstractOverloadsWithoutImplementationAllowed]
from abc import abstractmethod
from typing import overload, Union

class Foo:
@overload
@abstractmethod
def foo(self, value: int) -> int:
...
@overload
@abstractmethod
def foo(self, value: str) -> str:
...

class Bar(Foo):
@overload
def foo(self, value: int) -> int:
...
@overload
def foo(self, value: str) -> str:
...

def foo(self, value: Union[int, str]) -> Union[int, str]:
return super().foo(value) # E: Call to abstract method "foo" of "Foo" with trivial body via super() is unsafe