Skip to content

"Type of TypedDict is ambiguous" despite tag fields being distinct Literal types #8533

Closed
@florimondmanca

Description

@florimondmanca

Hi there,

Thanks for all the awesome work on mypy! It's brought incredible improvements to my workflow. :-)

I'm reporting what could be a bug with tagged unions, which were released in 0.770. As of today this is also reproducible against master.

Unfortunately this bug makes usage of tagged unions impractical. Last time I beta-tested it (a few days before the 0.770 release — perhaps around March 1st), it worked though.

Let me know if there's anything I can do to help resolve!

Reproduction case

# example.py
from typing import TypedDict, Literal, Union

# TypedDict interfaces with distinct tag fields.
A = TypedDict('A', {'@type': Literal['type-a'], 'value': str})
B = TypedDict('B', {'@type': Literal['type-b'], 'value': str})

# Tagged union of A and B.
C = Union[A, B]

c: C = {
    '@type': 'type-a',
    'value': 'test',
}

Expected behavior

$ mypy example.py
# OK - no errors

Actual behavior

$ mypy example.py
example.py:7:8: error: Type of TypedDict is ambiguous, could be any of ("A", "B")
example.py:7:8: error: Incompatible types in assignment (expression has type "Dict[str, str]", variable has type "Union[A, B]")
Found 2 errors in 1 file (checked 1 source file)

Version info

  • Python 3.8.1
  • Mypy 0.770
  • Mypy flags: none (and no mypy.ini in the current workdir).

Additional context

I notice an ambiguous case is tested here:

[case testTypedDictUnionAmbiguousCase]
from typing import Union, Mapping, Any, cast
from typing_extensions import TypedDict, Literal
A = TypedDict('A', {'@type': Literal['a-type'], 'a': str})
B = TypedDict('B', {'@type': Literal['a-type'], 'a': str})
c: Union[A, B] = {'@type': 'a-type', 'a': 'Test'} # E: Type of TypedDict is ambiguous, could be any of ("A", "B") \
# E: Incompatible types in assignment (expression has type "Dict[str, str]", variable has type "Union[A, B]")
[builtins fixtures/dict.pyi]

But the snippet above is unambiguous: Literal['type-a'] and Literal['type-b'] don't overlap at all. Is the test above passing in master?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions