Skip to content

Tagged unions don't work with Enums #12432

Closed
@hackaugusto

Description

@hackaugusto

Bug Report

With the example below, the second if doesn't properly narrow the type, it works fine if the Literal['b'] instead of the enum version.

To Reproduce

from queue import Queue
from typing import Literal, TypedDict, Union
from enum import Enum, unique

@unique
class Tag(Enum):
    a = 'a'
    b = 'b'

class OpA(TypedDict):
    tag: Literal[Tag.a]
    a: str

class OpB(TypedDict):
    tag: Literal[Tag.b]
    b: str

Ops = Union[OpA, OpB]

def do(op: Ops):
    if op['tag'] == Tag.a:
        reveal_type(op)
    if op['tag'] == Tag.b:
        reveal_type(op)

Expected Behavior

    if op['tag'] == Tag.b:
        reveal_type(op)

Should report:

t.py:24: note: Revealed type is "TypedDict('t.OpB', {'tag': Literal[t.Tag.b], 'b': builtins.str})"

Actual Behavior

Reported type is:

t.py:24: note: Revealed type is "Union[TypedDict('t.OpA', {'tag': Literal[t.Tag.a], 'a': builtins.str}), TypedDict('t.OpB', {'tag': Literal[t.Tag.b], 'b': builtins.str})]"

Your Environment

  • Mypy version(s) used: mypy 0.910, mypy 0.941, mypy 0.950+dev.fd8a15e1abdd2bb4f75c3a6319ebfba233e1fe8e (compiled: no)
  • Mypy command-line flags: mypy t.py
  • Mypy configuration options from mypy.ini (and other config files): nothing
  • Python version used: Python 3.10.2
  • Operating system and version: Fedora Linux 35

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions