You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至NumPy 1.22后出现新的mypy类型检查错误求助

NumPy 1.22.4升级后mypy 0.910类型检查报错的解决方案确认

把NumPy从1.21升级到1.22.4后,原本能通过mypy 0.910类型检查的代码出现了三类新错误,以下是错误分析、现有处理的正确性验证及更优方案:

1. 类型错误:signedinteger[_8Bit]不可索引

报错场景

x: np.ndarray 
v: float

# mypy报错:error: Value of type "signedinteger[_8Bit]" is not indexable
xn = np.int8(np.sign(np.atleast_1d(x).ravel() - v))
xn[0]

# mypy无报错
xn = np.array(np.sign(np.atleast_1d(x).ravel() - v), dtype=np.int8)
xn[0]

原因分析

NumPy 1.22优化了类型注解,np.int8()作为构造函数时,若传入标量会返回np.int8标量类型(而非数组)。当np.sign()的计算结果为标量时,np.int8()就会返回不可索引的标量,触发mypy报错。而np.array(..., dtype=np.int8)会强制返回数组类型,符合后续索引操作的类型要求。

方案确认与优化

现有处理方式是正确的。更简洁的替代方案可以用astype直接转换数组类型,避免额外的数组构造:

xn = np.sign(np.atleast_1d(x).ravel() - v).astype(np.int8)
xn[0]

2. 赋值类型不兼容:float与floating[Any]类型不匹配

报错场景

import numpy as np

def get_my_float(flt: float) -> float:
    return flt

# mypy报错:error: Incompatible types in assignment (expression has type "float", variable has type "floating[Any]")
get_my_float(np.average([2, 3]))

# mypy无报错(临时解决方案)
get_my_float(float(np.average([2, 3])))

原因分析

NumPy 1.22将np.average()的返回类型细化为np.floating[Any],而mypy 0.910认为Python原生float与NumPy浮点类型属于不同的类型体系,因此触发类型不兼容报错。

方案确认与优化

现有通过float()强制转换的方式是可行的。另外两种替代方案:

  • 使用类型转换注解:
    from typing import cast
    get_my_float(cast(float, np.average([2, 3])))
    
  • 升级mypy到较新版本(如0.990+),新版本对NumPy类型的兼容性更好,可能自动识别np.floating[Any]与原生float的兼容关系。

3. 返回值错误:assert_approx_equal无返回值

报错场景

import numpy as np
# 计算参考解ref
# 计算近似解app

# mypy报错
np.testing.assert_approx_equal(app, ref)

# 临时解决方案:抑制报错
np.testing.assert_approx_equal(app, ref)  # type: ignore

原因分析

这是NumPy与mypy的已知兼容性问题,np.testing模块中的断言函数的类型注解存在缺陷,导致mypy错误地检测到返回值相关问题。

方案确认

目前使用# type: ignore抑制报错是最直接的解决方案。如果项目中测试文件单独管理,也可以配置mypy忽略测试目录的类型检查,避免逐个添加注解。

内容的提问来源于stack exchange,提问作者Pietro D'Antuono

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:10:31