(Python,Numpy:类型提示),如何正确将“integer”值转换为“_DType@clip”?

(Python, Numpy: type hinting), How to correctly convert "integer" value to "_DType@clip"?

提问人:Garid 提问时间:7/8/2023 最后编辑:Garid 更新时间:7/20/2023 访问量:193

问:

我在类型提示方面遇到了问题。 假设以下代码 ():Numpy (version 1.25)/tmp/asdf.py

import numpy as np

tx: int = 32 
out_tx = np.clip(
        tx,
        0, 
        100,
        )

pyright给我以下错误:

$ pyright /tmp/asdf.py
/tmp/asdf.py
  /tmp/asdf.py:5:9 - error: Argument of type "Literal[32]" cannot be assigned to parameter "a" of type "ndarray[_DType@clip]" in function "clip"
    "Literal[32]" is incompatible with "ndarray[_DType@clip]" (reportGeneralTypeIssues)
  /tmp/asdf.py:6:9 - error: Argument of type "Literal[0]" cannot be assigned to parameter "a_min" of type "_DType@clip" in function "clip"
    Type "Literal[0]" is incompatible with constrained type variable "_DType" (reportGeneralTypeIssues)
  /tmp/asdf.py:7:9 - error: Argument of type "Literal[100]" cannot be assigned to parameter "a_max" of type "_DType@clip" in function "clip"
    Type "Literal[100]" is incompatible with constrained type variable "_DType" (reportGeneralTypeIssues)
3 errors, 0 warnings, 0 informations
  • 如何正确地将 Literal 转换为 ,这样就不会输出此消息?"integer"Numpy's "_DType@clip"pyright

更新:

  • 我忘了说我在.numpy v1.25
  • 开 ,不输出任何警告numpy v.1.24pyright
  • 我知道上面的代码有效。
  • 我只是在寻找最安全的写作方式,因为我真的很喜欢静态分析器/linter/LSP。
python numpy 转换 类型提示 pyright

评论

0赞 Daniil Fajnberg 7/8/2023
无需转换任何东西。您的代码是正确的。这些类型与其中一个重载签名匹配。这一定是 Pyright 的错误。Mypy对此代码也没有问题。

答:

0赞 Garid 7/8/2023 #1

显然,以下修复了最后 2 个警告:

import numpy as np

tx: int = 32
out_tx = np.clip(
    np.int32(tx),    # still expects array, produces warning
    np.int32(0),     # this fixed
    np.int32(100),   # this fixed
)
1赞 Anoma 7/8/2023 #2

答案 1

Pyright 应该不会返回错误,首先尝试重新安装 pyright 和 numpy。pip install --upgrade --force-reinstall pyright numpy

如果它不起作用,如 pyright 文档中所述:

无论搜索路径如何,Pyright 总是尝试使用类型存根 (“.pyi”) 文件解析导入,然后再回退到 python 源 (“.py”) 文件。

Numpy 有这些 .pyi 文件,对于以整数为参数的 clip 函数,我们有 https://github.com/numpy/numpy/blob/main/numpy/core/fromnumeric.pyi#L397-L408

@overload
def clip(
    a: _ScalarLike_co,
    a_min: None | ArrayLike,
    a_max: None | ArrayLike,
    out: None = ...,
    *,
    dtype: None = ...,
    where: None | _ArrayLikeBool_co = ...,
    order: _OrderKACF = ...,
    subok: bool = ...,
    signature: str | tuple[None | str, ...] = ...,
) -> Any: ...

有了这个,您的情况应该没有错误。

因此,看起来您的 pyright 考虑了一些存根文件(否则请求的类型将是 Any,而不是“_DType@clip”),而不是来自 Numpy 的文件。您可以尝试使用类似于最知名 IDE 的“转到定义”之类的选项来找到它。

答案 2

你可以使用 typing.cast,但这意味着对 pyright 撒谎以匹配已经很糟糕的函数的签名clip

import typing
import numpy as np

tx: int = 32
out_tx = np.clip(
        typing.cast(np.ndarray, tx),
        typing.cast(np.ndarray, 0),
        typing.cast(np.ndarray, 1),
        )

或者代替 ,不返回警告的每个类型np.ndarray

0赞 Garid 7/20/2023 #3

我发现为什么在不应该输出错误时输出错误:pyright

原因是我也安装了软件包。 而且它似乎覆盖了打字。data-science-typesnumpy

卸载后(使用 )不会再次输出此错误。pip3 uninstall data-science-typespyright