Thanks to visit codestin.com
Credit goes to github.com

Skip to content

tagged union of unions #9308

Description

@euri10

Report Type: Bug

Example: https://mypy-play.net/?mypy=latest&python=3.8&gist=529e99849ebe65749d8568b743f21050

I saw #8925.

It could be seen as a duplicate, not sure about it, but this one looks slightly different and more general as the one linked above, it's not only about None in unions but more about unions of unions where mypy has difficulties to narrow the correct TypedDict

from typing import Literal, TypedDict, Union

class NewJobEvent(TypedDict):
    tag: Literal["new-job"]
    job_name: str
    config_file_path: str

class CancelJobEvent(TypedDict):
    tag: Literal["cancel-job"]
    job_id: int

class AnotherOne(TypedDict):
    tag: Literal["another"]
    another: int


Event = Union[NewJobEvent, CancelJobEvent]

AnotherUnionEvent = Union[Event, AnotherOne]

event: Event
if event["tag"] == "new-job":
    reveal_type(event)
else:
    reveal_type(event)
    

another_union_event: AnotherUnionEvent
if another_union_event["tag"] == "new-job":
    reveal_type(another_union_event)
else:
    reveal_type(another_union_event)
  • What is the actual behavior/output?
main.py:23: note: Revealed type is 'TypedDict('main.NewJobEvent', {'tag': Literal['new-job'], 'job_name': builtins.str, 'config_file_path': builtins.str})'
main.py:25: note: Revealed type is 'TypedDict('main.CancelJobEvent', {'tag': Literal['cancel-job'], 'job_id': builtins.int})'
main.py:30: note: Revealed type is 'Union[TypedDict('main.NewJobEvent', {'tag': Literal['new-job'], 'job_name': builtins.str, 'config_file_path': builtins.str}), TypedDict('main.CancelJobEvent', {'tag': Literal['cancel-job'], 'job_id': builtins.int}), TypedDict('main.AnotherOne', {'tag': Literal['another'], 'another': builtins.int})]'
main.py:32: note: Revealed type is 'Union[TypedDict('main.NewJobEvent', {'tag': Literal['new-job'], 'job_name': builtins.str, 'config_file_path': builtins.str}), TypedDict('main.CancelJobEvent', {'tag': Literal['cancel-job'], 'job_id': builtins.int}), TypedDict('main.AnotherOne', {'tag': Literal['another'], 'another': builtins.int})]'
  • What is the behavior/output you expect?
    I would expect the union of union to be narrowed

  • What are the versions of mypy and Python you are using?
    v0.782

  • Do you see the same issue after installing mypy from Git master?
    yes

  • What are the mypy flags you are using? (For example --strict-optional)

[mypy]
disallow_untyped_defs = True
ignore_missing_imports = True

Activity

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