python-3.x - 让 mypy 警告不同类型变量的相等性检查

标签 python-3.x types static-typing mypy

mypy --strict 允许使用以下最小示例,不会出现任何错误:

a: int = 1
b: str = '1'

if a == b:
    pass
else:
    pass

是否有可能使其发出有关 if a == b: 行的错误(或至少是警告)?

最佳答案

编辑:下面我的原始答案描述了如何通过编写自定义 mypy 插件来实现这一点。

但是,as of mypy 0.700 ,现在可以直接通过 --strict-equality 标志来完成此操作。请注意,截至撰写本文时,默认情况下未通过 --strict 标志启用此标志。

例如,在上面的原始程序上运行 mypy 将产生以下错误:

test.py:4: error: Non-overlapping equality check (left operand type: "int", right operand type: "str")

您可以在Miscellaneous strictness options底部附近找到有关此标志的更多详细信息。 mypy 命令行标志文档部分。


这可以使用(当前处于实验阶段且未记录的)插件 API 来实现。

简而言之,在项目中的某个位置添加以下文件:

from typing import Callable, Optional, Type
from mypy.plugin import MethodContext, Plugin
from mypy.meet import is_overlapping_types

class StrictEqualityPlugin(Plugin):
    def get_method_hook(self, fullname: str) -> Optional[Callable[[MethodContext], Type]]:
        if fullname.endswith('__eq__') or fullname.endswith('__ne__'):
            return strict_check_callback

def strict_check_callback(ctx: MethodContext) -> Type:
    if len(ctx.arg_types) == 1 and len(ctx.arg_types[0]) == 1:
        # Note: Expressions of the form 'base_type == arg_type' get
        # translated into `base_type.__eq__(arg_type)`.
        base_type = ctx.type
        arg_type = ctx.arg_types[0][0]

        # Two types are overlapping if one of the types could potentially be the
        # same as or a subtype of the other.
        #
        # If you want something even stricter, add `from mypy.sametypes import is_same_type`
        # up at the top and call `is_same_type` instead of `is_overlapping_types`.
        if not is_overlapping_types(base_type, arg_type):
            ctx.api.msg.warn(
                "The left and right operands have disjoint types ({} and {})".format(
                    ctx.api.msg.format(base_type),
                    ctx.api.msg.format(arg_type),
                ), 
                ctx.context)
    return ctx.default_return_type

def plugin(mypy_version: str) -> Plugin:
    return StrictEqualityPlugin

假设该文件的名称是 strict_equality_plugins.py

然后,在项目的顶层创建一个 mypy.ini文件。该文件至少应包含以下内容:

[mypy]
plugins = ./path/to/strict_equality_plugins.py

然后,在根项目中运行 mypy 将产生如下错误:

foo.py:1: warning: The left and right operands have disjoint types ("int" and "str")

免责声明: mypy 项目的插件 API 是高度实验性的——我不 promise 该插件将在 mypy 的 future 版本中继续未经修改地工作。

关于python-3.x - 让 mypy 警告不同类型变量的相等性检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52125248/

相关文章:

csv - UnicodeDecodeError : 'charmap' codec can't decode byte 0x8d in position 7240: character maps to <undefined>

python - 在Python中解析一行中的多个变量类型

design-patterns - 静态类型检查的设计模式

functional-programming - 实现 Monad 的语言必须是静态类型的吗?

java - Java 风格的 Groovy 和 Java 一样快吗?

python-3.x - pandas dataframe通过两个值的平均值填充nan

python - 从 2 个列表中查找相关系数

c - float 转换方法

c# - 在枚举中指定底层类型的用例是什么?

scala - 无法使用静态语言创建应用函数?