Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

overload following optional argument

I have a class Animal with a method foo which has different return types according to a boolean parameter inplace which follows an optional parameter bar. I'd like to overload the function so that the return type is known if the value of inplace is known

Here's my code:

# main.py

from __future__ import annotations

from typing import Optional, overload, Literal 


class Animal:
    @overload
    def foo(self, bar=..., inplace: Literal[False]=...) -> Animal:
        ...

    @overload
    def foo(self, bar=..., inplace: Literal[True]=...) -> None:
        ...

    def foo(
        self, bar=None, inplace: bool = False
    ) -> Optional[Animal]:
        ...


reveal_type(Animal().foo(bar='a'))
reveal_type(Animal().foo(inplace=True))
reveal_type(Animal().foo(inplace=False))
$ mypy main.py
main.py:8: error: Overloaded function signatures 1 and 2 overlap with incompatible return types
main.py:21: note: Revealed type is 'main.Animal'
main.py:22: note: Revealed type is 'None'
main.py:23: note: Revealed type is 'main.Animal'
Found 1 error in 1 file (checked 1 source file)

https://mypy-play.net/?mypy=latest&python=3.9&gist=49da369f6343543769eed2060fa61639

How can I avoid the Overloaded function signatures 1 and 2 overlap with incompatible return types error on line 8?

like image 456
ignoring_gravity Avatar asked Feb 28 '26 10:02

ignoring_gravity


1 Answers

This seems to work:

from __future__ import annotations

from typing import Optional, overload, Literal 


class Animal:

    # using defaults
    @overload
    def foo(self, bar=..., inplace: Literal[False]=...) -> Animal: ...

    # using inplace = True
    
    # with bar
    @overload
    def foo(self, bar, inplace: Literal[True]) -> None: ...

    # without bar
    @overload
    def foo(self, *, inplace: Literal[True]) -> None: ...

    # with bool
    @overload
    def foo(self, bar=..., inplace: bool=...) -> Optional[Animal]: ...

    def foo(
        self, bar=None, inplace = False
    ):
        ...


reveal_type(Animal().foo(bar='a'))
reveal_type(Animal().foo(bar='a', inplace=True))
reveal_type(Animal().foo(bar='a', inplace=False))
reveal_type(Animal().foo(inplace=True))
reveal_type(Animal().foo(inplace=False))
reveal_type(Animal().foo())

inplace: bool
reveal_type(Animal().foo(bar='a', inplace=inplace))
reveal_type(Animal().foo(inplace=inplace))

Lots of overloads, but perhaps that's inevitable here

like image 118
ignoring_gravity Avatar answered Mar 02 '26 00:03

ignoring_gravity