Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to overload depending on the presence of an argument? #248

Closed
dmoisset opened this issue Jul 18, 2016 · 3 comments
Closed

Comments

@dmoisset
Copy link
Contributor

I'm not sure if this is an issue, a feature request, or a question...

While trying to write typesheds for numpy I found this (simplified) situation:

I have a method with the following signature

T = TypeVar('T')
def foo(self, arg1: int=..., arg2: int=..., *, out: T=None):

The function returns a bool when the out argument is not present (so foo(), foo(x, y), foo(arg2=x) all are boolean values).

The function returns a T when the out argument is present (so foo(out="hello"), foo(x, y, out="hello"), foo(out="hello", arg2=x) all are string values).

I was trying to describe that as an overload (and restricting to keyword only args to avoid mistakes):

from typing import TypeVar, overload

T = TypeVar('T')

class C:
    @overload
    def foo(self, *, arg1: int=0, arg2: int=0) -> bool: ...
    @overload
    def foo(self, *, arg1: int=0, arg2: int=0, out:T=None) -> T: ...

reveal_type(C().foo())
reveal_type(C().foo(out="hello"))

but the revealed_type for the result of the first call is "Any". I don't think my definition should be ok (my overloaded signatures are ambiguous), but an Any there is certainly unexpected there. Also, I'm not sure what would be (if possible) the way to express this situation with mypy's type system

@gvanrossum
Copy link
Member

I was going to reply that the problem is that you gave the second variant a default value for out -- so a call without out matches both variants. And I think that should be the correct answer. But removing the default for out doesn't change the output -- it still thinks that the first call returns None. So I think that's a bug. (And it doesn't need a type variable to repro -- I still get the same behavior if I replace T with str in the second variant.

@ilevkivskyi
Copy link
Member

@dmoisset I also think that the second variant should have no default, i.e. out:T=None should be replaced by simply out:T. As I see this is a bug in mypy, not a bug in typing.py, so that you probably should open an issue there.

@dmoisset
Copy link
Contributor Author

I wasn't award that keyword-only args were allowed to be mandatory (i.e. no default), that probably solves this at specification level, so I'll close this and open a simpler case as a bug in mypy regarding the "Any", thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants