Mypy 抱怨 [no-any-return] 规则因明显的布尔表达式而被违反

问题描述 投票:0回答:1

以下代码抛出mypy错误:

from typing import Dict, Any

def asd(x: Dict[str, Any]) -> bool:
    return x['a'] == 1

asd({"x": 2})

IMO 什么作为命令通过并不重要。

x['a'] == 1
应始终为布尔值。但是 mypy 抱怨:

test.py:4: error: Returning Any from function declared to return "bool"  [no-any-return]

除了用

# type: ignore[no-any-return]
填充我们的代码库之外,还有什么解决方法吗?

我的setup.cfg供参考:

namespace_packages = True
explicit_package_bases = True
check_untyped_defs = True
warn_return_any = True
warn_unused_ignores = True
show_error_codes = True
python-3.x mypy python-typing
1个回答
2
投票

__eq__
方法,Python丰富的比较方法之一,并不always返回
True
False
,它也可以返回
NotImplemented
(或其他值)。

这用于,例如,在第一种类型无法与第二种类型进行比较的情况下,因此

a.__eq__(b)
返回
NotImplemented
。在这种情况下,它会尝试
b.__eq__(a)
作为回退 (a)。如果那个 also 返回
NotImplemented
,那么我相信它会回到基本的
object
类型来找出相等性。

您可以看到

mypy
在其源代码中为此定义类型的方式,特别是
mypy/mypy/typeshed/stdlib/_operator.pyi

def eq(__a: object, __b: object) -> Any: ...

这就是为什么你会收到那条特定的信息。

作为快速修复,您可以更改函数以返回

bool(x['x'] == 1)
。这 正是 Python 本身在评估布尔上下文中的返回值时所做的,因此应该可以接受
mypy
(b).


(a)比那复杂little,还涉及两个项目的层次类型关系,但底线仍然存在:丰富的比较运算符并不总是返回

bool


(b) 数据模型的 Python 文档(我的重点)中对此进行了介绍:

丰富的比较方法可能会返回单例

NotImplemented
如果它没有为给定的参数对实现操作。按照惯例,返回
False
True
以进行成功比较。但是,这些方法可以返回 any 值,因此如果在布尔上下文中使用比较运算符(例如,在
if
语句的条件中),Python 将调用
bool()
值以确定是否结果是真还是假。

有趣的是,虽然这不会改变这个答案的有效性,但之后的部分指出:

默认情况下,

object
通过使用
__eq__()
实现
is
,在错误比较的情况下返回
NotImplemented
True if x is y else NotImplemented
.

但我不相信这是准确的。在实际代码中,

==
!=
似乎都会导致
True
False
,具体取决于对象身份,并且永远不会返回
NotImplemented
或引发异常(异常仅发生在排序比较时像
<
>=
):

/* If neither object implements it, provide a sensible default
   for == and !=, but raise an exception for ordering. */
switch (op) {
    case Py_EQ:
        res = (v == w) ? Py_True : Py_False;
        break;
    case Py_NE:
        res = (v != w) ? Py_True : Py_False;
        break;
    default:
        _PyErr_Format(tstate, PyExc_TypeError, ...

正如评论中指出的那样,身份检查是在不同级别对基础对象进行的,例如,type objects。所以 我会对文档的那部分持保留态度 :-)

© www.soinside.com 2019 - 2024. All rights reserved.