mypy:无法推断“map”的类型参数 1

Inf*_*ity 5 python python-3.x type-annotation python-3.6 mypy

当尝试使用 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
Run Code Online (Sandbox Code Playgroud)

mypy 抛出以下错误:

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

为什么会出现这个错误?我该如何修复它?

谢谢 :)

编辑:这实际上是 mypy 中的一个错误,现在已修复。

Jac*_*din 4

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

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

mypy 的当前状态是它的类型推断不是无限制的。(该项目还有600 多个未解决的问题。

我相信您的问题可能与问题 #1855有关。我相信情况确实如此,因为DigitsSequence = strDigitsSequence = Sequence[int]两者都有效,而DigitsSequence = Union[str, Sequence[int]]无效。

一些解决方法:

  1. 请改用 lambda 表达式:

    new_digits = list(map(lambda s: str(s), digits))
    
    Run Code Online (Sandbox Code Playgroud)
  2. 重新转换为新变量:

    any_digits = digits # type: Any
    new_digits = list(map(str, any_digits))
    
    Run Code Online (Sandbox Code Playgroud)
  3. 让 mypy 忽略该行:

    new_digits = list(map(str, digits)) # type: ignore
    
    Run Code Online (Sandbox Code Playgroud)