【问题标题】:mypy: Cannot infer type argument 1 of "map"mypy:无法推断“map”的类型参数 1
【发布时间】:2017-07-08 16:08:07
【问题描述】:

尝试使用 mypy 检查以下代码时:

import itertools
from typing import Sequence, Union, List
        
DigitsSequence = Union[str, Sequence[Union[str, int]]]


def normalize_input(digits: DigitsSequence) -> List[str]:
    try:
        new_digits = list(map(str, digits))  # <- Line 17
        if not all(map(str.isdecimal, new_digits)):
            raise TypeError
    except TypeError:
        print("Digits must be an iterable containing strings.")
        return []
    return new_digits

mypy 抛出以下错误:

calculate.py:17: 错误:无法推断“map”的类型参数 1

为什么会出现这个错误?我该如何解决?

谢谢:)

编辑:它实际上是 mypy 中的 bug,现在已修复。

【问题讨论】:

  • 考虑到str is basically Sequence[str],您可以将Union[str, Sequence[Union[str, int]]] 重写为Sequence[Union[str, int]],然后错误消失。

标签: python python-3.x python-3.6 mypy type-annotation


【解决方案1】:

您可能已经知道,mypy 依赖于typeshed 来存根 Python 标准库中的类和函数。我相信您的问题与 typeshed 的 stubbing of map:

@overload
def map(func: Callable[[_T1], _S], iter1: Iterable[_T1]) -> Iterator[_S]: ...

而且 mypy 的当前状态使得它的类型推断不是无限的。 (该项目还有over 600 open issues.

我相信您的问题可能与issue #1855 有关。我相信是这样的,因为DigitsSequence = strDigitsSequence = Sequence[int] 都可以工作,而DigitsSequence = Union[str, Sequence[int]] 不行。

一些解决方法:

  1. 改用 lambda 表达式:

    new_digits = list(map(lambda s: str(s), digits))
    
  2. 重新转换为一个新变量:

    any_digits = digits # type: Any
    new_digits = list(map(str, any_digits))
    
  3. 要求 mypy 忽略该行:

    new_digits = list(map(str, digits)) # type: ignore
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-20
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    相关资源
    最近更新 更多