Skip to content

Handle assignments to a TypedDict with {**mapping} correctly #14946

Closed
@a-recknagel

Description

@a-recknagel

Bug Report

I'm not sure what I'm doing wrong, and the error message from mypy doesn't give me too much insight. So this might be a bug, a documentation issue, or a case of me being daft.

To Reproduce

from typing import TypedDict, Optional

class Foo(TypedDict, total=False):
    a: bool
    b: bool
    c: bool

def bar(foo: Optional[Foo] = None) -> Foo:
    if foo is None:
        foo = {}
    foo = {"a": False, **foo, "b": False}  # this is "line 11"
    return foo

Expected Behavior

From looking at it alone, I expected this snippet to pass mypy without errors. The errors don't depend on total=False, it's just easier to write an example that way.

Actual Behavior

~/typed_dicts_test.py:11: error: Incompatible types in assignment (expression has type "Dict[str, bool]", variable has type "Optional[Foo]")  [assignment]
~/typed_dicts_test.py:11: error: Expected TypedDict key to be string literal  [misc]
~/typed_dicts_test.py:11: error: Argument 1 to "update" of "MutableMapping" has incompatible type "Foo"; expected "SupportsKeysAndGetItem[str, bool]"  [arg-type]
~/typed_dicts_test.py:11: note: Following member(s) of "Foo" have conflicts:
~/typed_dicts_test.py:11: note:     Expected:
~/typed_dicts_test.py:11: note:         def __getitem__(self, str, /) -> bool
~/typed_dicts_test.py:11: note:     Got:
~/typed_dicts_test.py:11: note:         def __getitem__(self, str, /) -> object
Found 3 errors in 1 file (checked 1 source file)

The Argument 1 to "update" of "MutableMapping" has incompatible type "Foo" in particular trips me up. Skipping the assignment in line 11 and returning right away or assigning to something like baz: Foo instead reduces the emount of errors to error: Expected TypedDict key to be string literal, but I'd like to avoid that if possible.

My Environment

  • Mypy version used: 1.1.1 (compiled: yes)
  • Mypy command-line flags: /
  • Mypy configuration options from mypy.ini (and other config files): /
  • Python version used: 3.10.10

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions