Skip to content

Type is dropped from a Union when using TypedDicts with optional fields #11840

Closed
@mschurr

Description

@mschurr

Bug Report

It seems like types can be dropped from a union when using TypedDicts with optional fields.

Reproduction

from typing import List, Sequence, TypedDict, Union

class TypeA(TypedDict):
    fieldB: str
    fieldC: bool

class _TypeB(TypedDict):
    fieldA: str
    fieldB: str

class TypeB(_TypeB, total=False):
    fieldC: bool

ComponentT = Union[TypeA, TypeB]
ComponentListT = List[ComponentT]  # Using List or Sequence causes an error.

def process(val: ComponentT) -> ComponentT:
    return val

def example(val: ComponentListT) -> ComponentListT:
    return [process(part) for part in val]
# Run with:
$ mypy test.py

Expected Behavior

This should type-check correctly.

Actual Behavior

mypy_test2.py:21: error: Incompatible return value type (got "List[TypeA]", expected "List[Union[TypeA, TypeB]]")
mypy_test2.py:21: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
mypy_test2.py:21: note: Consider using "Sequence" instead, which is covariant
mypy_test2.py:21: error: List comprehension has incompatible type List[Union[TypeA, TypeB]]; expected List[TypeA]
Found 2 errors in 1 file (checked 1 source file)

Note that using Sequence instead, as suggested, results in:

mypy_test2.py:21: error: List comprehension has incompatible type List[Union[TypeA, TypeB]]; expected List[TypeA]
Found 1 error in 1 file (checked 1 source file)

It seems like TypeB is somehow being lost from the Union?

Your Environment

  • Python 3.8.0
  • mypy 0.910
  • Ubuntu 18.04

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions