Skip to content

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

Closed

Description

@dmoisset

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

Activity

  1. gvanrossum commented on Jul 19, 2016

    @gvanrossum
    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.

  2. ilevkivskyi commented on Jul 19, 2016

    @ilevkivskyi
    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.

  3. dmoisset commented on Jul 19, 2016

    @dmoisset
    ContributorAuthor

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions