python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.38k stars 2.82k forks source link

Possible regression in 1.7 with dict unions (PEP 584) #16572

Closed Tinche closed 11 months ago

Tinche commented 11 months ago

There's a change for sure, but I'm having trouble figuring out if the old or new behavior is correct.

I skimmed the Mypy changelog but didn't find much about this.

Quick reproducer:

from collections.abc import Mapping

a: Mapping[str, str] = {}

{"a": "a"} | a

On 1.6: no error. On 1.7:

a05.py:5: error: No overload variant of "__or__" of "dict" matches argument type "Mapping[str, str]"  [operator]
a05.py:5: note: Possible overload variants:
a05.py:5: note:     def __or__(self, dict[str, str], /) -> dict[str, str]
a05.py:5: note:     def [_T1, _T2] __or__(self, dict[_T1, _T2], /) -> dict[str | _T1, str | _T2]

The PEP gives the following pseudocode for __or__:

def __or__(self, other):
    if not isinstance(other, dict):
        return NotImplemented
    new = dict(self)
    new.update(other)
    return new

So I guess the new behavior might be more correct? It feels less useful though.

AlexWaygood commented 11 months ago

Duplicate of #16489.

The behaviour change is as a result of this typeshed change: https://github.com/python/typeshed/pull/10679. The new behaviour is more accurate, and the change was made to fix a false negative that was reported by a user to typeshed: https://github.com/python/typeshed/issues/10678.

Tinche commented 11 months ago

Cool, thanks. Wish we had a frozendict!

I tried searching for duplicates but I couldn't find any. GitHub issue search could be better :/