Skip to content

Apparent False Positive With Dict Update Method #5849

Closed

Description

@lvfrazao

Please provide more information to help us understand the issue:
When I define a somewhat complex and heterogeneous dictionary (meant to later be converted to JSON) it causes mypy to alert me to errors which I do not believe are valid.

  • Are you reporting a bug, or opening a feature request?

Bug

  • Please insert below the code you are checking with mypy,
    or a mock-up repro if the source is private. We would appreciate
    if you try to simplify your case to a minimal repro.
from typing import Union, Dict

class A(object):
    def __init__(self, user: Dict[str, Union[str, bool, list, Dict[str, Union[bool, list]]]]):
        d1 = {
            'a': user['name'],
        }

        d2 = {
            'c': 3,
        }

        self.d3 = {**d1, **d2}

print(A({'name': 'victor'}).d3)
  • What is the actual behavior/output?
lvrf@LAPTOP-D0LJCLS0:~$ mypy sample_mypy_code.py
sample_mypy_code.py:13: error: Argument 1 to "update" of "dict" has incompatible type "Dict[str, int]"; expected "Mapping[str, Union[str, bool, List[Any], Dict[str, Union[bool, List[Any]]]]]"

Note, this behaviour only occurs when the 'user' input is typed.

  • What is the behavior/output you expect?

I would expect there to be no error for this operation.

  • What are the versions of mypy and Python you are using?
    Do you see the same issue after installing mypy from Git master?

mypy version 0.641

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

No flags

Activity

  1. lvfrazao commented on Oct 28, 2018

    @lvfrazao
    Author

    I would also appreciate any tips that anyone has on how to properly type annotate highly heterogeneous dictionaries to be used for the purpose of interacting with REST APIs.

  2. ilevkivskyi commented on Oct 28, 2018

    @ilevkivskyi
    Member

    I would also appreciate any tips that anyone has on how to properly type annotate highly heterogeneous dictionaries to be used for the purpose of interacting with REST APIs.

    https://mypy.readthedocs.io/en/latest/more_types.html#typeddict

    The issue itself is valid, and similar to how mypy overreacts to concatenating lists with different types, the latter can be just fixed in typeshed, while this one might require some special-casing. Btw, have you tried giving an explicit annotation to self.d3?

  3. lvfrazao commented on Oct 28, 2018

    @lvfrazao
    Author

    Thanks, typeddict looks very promising. I just tried giving self.d3 an explicit annotation and it appears to not make a difference (same error pops up when I run mypy).

  4. sirosen commented on Mar 12, 2021

    @sirosen

    I just came across an interesting variant of this error:

    class A:
        foo: typing.Dict[str, typing.Union[int, str]] = {"a": 1}
    
    class B(A):
        # incompatible type "Dict[str, Union[int, str]]"; expected "Mapping[str, str]"
        foo = {"b": "c", **A.foo}

    I assume that what's happening is that the type of the RHS of that assignment is being resolved before mypy is aware that B.foo should have the same type as A.foo.

    This can be fixed by annotating foo. But I think this is something of a problem for libraries which offer inheritance as part of their interface. If a 3rd party developer inherits from A, they have to annotate foo if they override it.

  5. jdferreira commented on Jun 29, 2021

    @jdferreira

    I've stumbled upon the same issue.

    class Question(typing.TypedDict):
        id: str
        body: str
    
    question: Question = {
        'id': 'something',
        'body': 'something else',
    }
    
    processed = {
        **question,
        'documents': []
    }

    Hinting with processed: dict seems to silence the warning. I think this solves the issue, but it would be awesome if mypy could derive the type of processed to be typing.TypedDict('<something...>', id=str, body=str, document=str). I don't know if mypy is capable of doing that, or if this type of inference has precedents, though.

  6. erictraut commented on Aug 10, 2023

    @erictraut

    This bug appears to have been fixed. The latest version of mypy doesn't emit an error for any of the above code samples.

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