Skip to content

mypy should support optional tagged unions #8925

@chdsbd

Description

@chdsbd

Report Type: Bug

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

from typing import Literal, TypedDict, Union

class NewJob(TypedDict):
    event_type: Literal["new-job"]
    job_description: str

class CancelJob(TypedDict):
    event_type: Literal["cancel-job"]
    job_id: int

request: Union[NewJob, CancelJob, None]

# works
if request is not None:
    if request["event_type"] == "new-job":
        print("Starting new job", request["job_description"])

# fails with `main.py:20: error: TypedDict "CancelJob" has no key 'job_description'`
if request is not None and request["event_type"] == "new-job":
    print("Starting new job", request["job_description"])
  • What is the actual behavior/output?
    Mypy does not discriminate TypedDicts when None is part of the Union.
  • What is the behavior/output you expect?
    Mypy narrows a Union of TypedDict and None like it does for unions of TypedDicts.
  • What are the versions of mypy and Python you are using?
    mypy 0.770
    Python 3.7.6
  • Do you see the same issue after installing mypy from Git master?
    I have not tried master.

This is a small issue because there is an easy workaround of checking for None before checking the tag.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions