Skip to content

Union types and generics #4432

Closed
Closed
@mitar

Description

@mitar

I have this example:

import typing

A = typing.TypeVar('A')

class Base(typing.Generic[A]):
    def do(self, input: A) -> A:
        return input

Inputs1 = typing.Union[int, str]

class Numbers1(Base[Inputs1]):
    pass

Inputs2 = typing.TypeVar('Inputs2', bound=typing.Union[int, str])

class Numbers2(Base[Inputs2]):
    pass

class Numbers3(Base[Inputs1]):
    def do(self, input: Inputs2) -> Inputs2:
        return input

reveal_type(1)  # This is line 23
reveal_type(Numbers1().do(1))
reveal_type(Numbers1().do('foobar'))
reveal_type(Numbers2().do(1))
reveal_type(Numbers2().do('foobar'))
reveal_type(Numbers3().do(1))
reveal_type(Numbers3().do('foobar'))

When I run mypy (mypy===0.570-dev-1aba774cc00b49627b86f95c8172adbb12b52891), I get:

test.py:23: error: Revealed type is 'builtins.int'
test.py:24: error: Revealed type is 'Union[builtins.int, builtins.str]'
test.py:25: error: Revealed type is 'Union[builtins.int, builtins.str]'
test.py:26: error: Revealed type is '<nothing>'
test.py:26: error: Argument 1 to "do" of "Base" has incompatible type "int"; expected <nothing>
test.py:27: error: Revealed type is '<nothing>'
test.py:27: error: Argument 1 to "do" of "Base" has incompatible type "str"; expected <nothing>
test.py:28: error: Revealed type is 'builtins.int*'
test.py:29: error: Revealed type is 'builtins.str*'

Ideally, Numbers1 should work like Numbers3, or at least Numbers2 should. But currently it seems like only Numbers3 make a strict return type and not union type. It is sad that I have to reimplement do method just to get correct return types. This is really going against DRY principle.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions