Skip to content

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

Closed

Description

@gvanrossum

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]"

Activity

  1. ilevkivskyi commented on Jun 12, 2018

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

  2. Michael0x2a commented on Jun 15, 2018

    @Michael0x2a
    Collaborator

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions