添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
大方的西装  ·  ST_Union·  1 周前    · 
重感情的伤疤  ·  SQL injection UNION ...·  1 周前    · 
傻傻的佛珠  ·  Mybatis union ...·  4 周前    · 
苦恼的闹钟  ·  Solved: ORA-01790: ...·  4 周前    · 
愤怒的骆驼  ·  Is there any way to ...·  2 月前    · 
不羁的闹钟  ·  AVAudioSession ...·  4 月前    · 
善良的牛腩  ·  ISRC申报平台 - ...·  8 月前    · 

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account
from typing import *
def example(value: Mapping[Union[str, int], Union[str, int]]):
x: Mapping[str, int] = {
    "a": 1,
    "b": 2,
    "c": 3
example(x) # <-- MyPy doesn't like this: Argument 1 to "example" has incompatible type "Mapping[str, int]"; expected "Mapping[Union[str, int], Union[str, int]]"mypy(error)

Results in error: Argument 1 to "example" has incompatible type "Mapping[str, int]"; expected "Mapping[Union[str, int], Union[str, int]]"mypy(error) .

Shouldn't MyPy accept the Mapping[str, int] to be a valid instance of Mapping[Union[str, int], Union[str, int]] ?

This behavior looks surprising, because Union is supported for values, but not for keys. If the function annotation is modified this way:

from typing import *
def example(value: Union[Mapping[str, Union[str, int]],
                         Mapping[int, Union[str, int]]]):
x: Mapping[str, int] = {
    "a": 1,
    "b": 2,
    "c": 3
example(x)

Then mypy is happy. Version: mypy==0.761

Additionally:

a: Union[Mapping[str, Union[str, int]],
         Mapping[int, Union[str, int]]]
b: Union[str, int] = 20
c = a[b]  < mypy reports two errors, written below
Invalid index type "Union[str, int]" for "Union[Mapping[str, Union[str, int]], 
Mapping[int, Union[str, int]]]"; expected type "str" mypy(error)
Invalid index type "Union[str, int]" for "Union[Mapping[str, Union[str, int]], 
Mapping[int, Union[str, int]]]"; expected type "int" mypy(error)
          

@JelleZijlstra, @hauntsaninja thank you for your replies! 🌞 I thought there was a good reason for this behavior.
I am closing this issue, since I see it was already discussed.

FWIW, I think I understood that Union is not the right tool to do the think I had in mind, described in my example above. The right tool is to define generic types for keys and values!

from typing import *
A = TypeVar("A", str, int)
B = TypeVar("B", str, int)
def example2(value: Mapping[A, B]):
x: Mapping[str, int] = {
    "a": 1,
    "b": 2,
    "c": 3
example2(x)
y: Mapping[str, str] = {
    "a": "1",
    "b": "2",
    "c": "3"
example2(y)

And I understood this, because in C# it would be the same (Union doesn't exist in C#, you have to use interfaces to describe something like union). I often take C# as example because I know it, it's static, and clearly it is mature about generics.

A basic example would be:

using System;
using System.Collections.Generic;
using System.Linq;
namespace netconsole
    class Program
        // a function that accepts any kind of dictionary as input and returns 
        // a new dictionary of only strings
        static Dictionary<string, string> Example<A, B>(Dictionary<A, B> dict)
            => dict.ToDictionary(key => key.ToString(), value => value.ToString());
        static void Main(string[] args)
            var x = new Dictionary<string, int>() {
                {"a", 1},
                {"b", 2},
                {"c", 3}
            var a = Example(x);