Skip to content

Overload on Optional[str] and bytes fails with arg of type Union[str, bytes] #5204

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

Closed
gvanrossum opened this issue Jun 12, 2018 · 2 comments
Closed
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-overloads

Comments

@gvanrossum
Copy link
Member

This may well be a known issue. @Michael0x2a. (The real code used os.listdir(), but I'm simplifying it here and it fails the same way.)

@overload
def listdir(a: Optional[str] = None): pass
@overload
def listdir(a: bytes): pass
def listdir(a): pass

def f(a: Union[bytes, str]):
  listdir(a)  # error: Argument 1 to "listdir" has incompatible type "Union[bytes, str]"; expected "Optional[str]"
@ilevkivskyi
Copy link
Member

Hm, if I remove the default value then it works:

@overload
def listdir(a: Optional[str]): pass
@overload
def listdir(a: bytes): pass
def listdir(a): pass

def f(a: Union[bytes, str]):
  listdir(a)  # OK

So must be some unnecessary restriction on arg kinds in union math and so probably easy to fix.

@ilevkivskyi ilevkivskyi added bug mypy got something wrong priority-1-normal false-positive mypy gave an error on correct code topic-overloads labels Jun 12, 2018
@Michael0x2a
Copy link
Collaborator

Michael0x2a commented Jun 15, 2018

Yeah, union math currently tries to handle only signatures where the argument kinds are all the same -- I wasn't sure how to go about unioning together callables that contain some crazy mixture of keyword arguments, name-only arguments, *args, **kwargs so decided to go for simplicity.

I don't think it would be too hard to extend the current logic so it handles the case where one kind is a positional and the other is an optional. I can add that to my TODO list.

Michael0x2a added a commit to Michael0x2a/mypy that referenced this issue Jun 15, 2018
Resolves python#5204.

This commit relaxes the union math logic so that it allows signatures
with arg kinds that are nearly identical except that one arg is
positional and the other is optional.

This commit also removes the "names must be the same" restriction mostly
so that the original example given in python#4576
will pass. (In retrospect, I think this check didn't really buy us much
-- even if the alternatives share the same arg names, there's no
guarantee the actual implementation signature will also share the same.)
Michael0x2a added a commit to Michael0x2a/mypy that referenced this issue Jun 15, 2018
Resolves python#5204.

This commit relaxes the union math logic so that it allows signatures
with arg kinds that are nearly identical except that one arg is
positional and the other is optional.

This commit also removes the "names must be the same" restriction mostly
so that the original example given in python#4576
will pass. (In retrospect, I think this check didn't really buy us much
-- even if the alternatives share the same arg names, there's no
guarantee the actual implementation signature will also share the same.)
Michael0x2a added a commit to Michael0x2a/mypy that referenced this issue Jun 15, 2018
Resolves python#5204.

This commit relaxes the union math logic so that it allows signatures
with arg kinds that are nearly identical except that one arg is
positional and the other is optional.

This commit also removes the "names must be the same" restriction mostly
so that the original example given in python#4576
will pass. (In retrospect, I think this check didn't really buy us much
-- even if the alternatives share the same arg names, there's no
guarantee the actual implementation signature will also share the same.)
Michael0x2a added a commit that referenced this issue Jun 16, 2018
…5222)

Resolves #5204.

This commit relaxes the union math logic so that it allows signatures
with arg kinds that are nearly identical except that one arg is
positional and the other is optional.

This commit also removes the "names must be the same" restriction mostly
so that the original example given in #4576
will pass. (In retrospect, I think this check didn't really buy us much
-- even if the alternatives share the same arg names, there's no
guarantee the actual implementation signature will also share the same.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-overloads
Projects
None yet
Development

No branches or pull requests

3 participants