当装饰器确保全局变量不是 None 时,Mypy 认为全局变量可以是 None,仅在带有 arg 的函数中

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

我试图确保服务器已设置装饰器, 代码按预期运行,但 mypy 给了我一个 union-attr 错误。

这是一个例子:

from functools import wraps


class Server:
    def __init__(self, ip) -> None:
        self.ip = ip


_server: Server | None = None


def ensure_server(func):
    """Ensure a server connection has been set"""

    @wraps(func)
    def wrapper(*args, **kwargs):
        global _server
        if _server is None:
            raise ValueError("server is None")
        return func(*args, **kwargs)

    return wrapper


@ensure_server
def hello_server():
    print(_server.ip)


def add_server(foo: str):
    print(_server.ip + foo)

Mypy 处理

hello_server
没有任何错误,但在
Item "None" of "Server | None" has no attribute "ip"
中给出
add_server

为什么 mypy 对带参数的函数给出错误,而对没有参数的函数则不给出错误?

python types decorator mypy
1个回答
0
投票

这里有两个问题。第一个问题是你没有把

@ensure_server
放在
add_server
上,所以你实际上并没有得到你认为在那里的保证。

但这并不是触发 mypy 行为的原因。

hello_server
没有注释,所以 mypy 根本不检查它。 mypy 不知道装饰器做了什么,也没有办法告诉 mypy 装饰器确保了你想要的不变量。

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