首页 > 解决方案 > 如何“投射” python 类型提示

问题描述

我有一个客户端库,它的功能看起来像这样

def connect(timeout: float):

但是,该客户端的文档指出,如果timeout未指定或 None 它将有效地使用默认超时。我已经测试过就是这种情况,它可以正常工作,指定 for 的Nonetimeout

然后,我的代码将这个连接方法包装成如下内容:

def my_connect(timeout: float = None):
    connect(timeout=timeout)

当我针对它运行 mypy 以验证类型提示时,它抱怨说:参数timeouttoconnect是期待float但得到了Optional[float]

我宁愿不必在我的代码中添加额外的逻辑来根据connect方法中是否使用默认值来更改我调用方法Nonemy_connect方式,因为这将需要额外的单元测试,以及我需要的全部原因超时首先是因为单元测试会在没有超时的情况下阻塞负面测试用例。

推荐的处理方法是什么?即使库创建者明确指定了非可选浮点数,是否有某种方法可以强制接受参数?该库是专有的且仅限二进制文件,因此我无法更改签名,我真的很想尝试在无需更改任何功能逻辑的情况下完成这项工作,只需类型提示。

标签: pythontypes

解决方案


我已经为此实现了一个解决方案,它似乎通过了所有检查,并且在功能上似乎是等效的。

同样,库签名是

def connect(timeout: float):

包装是:

def my_connect(timeout: float = None):

事实证明,该connect方法默认为socket._GLOBAL_DEFAULT_TIMEOUT如果值丢失或None. 这在文档中是正确的,我只是错过了。

解决方案是简单地将包装器上的默认值更改为使用相同socket._GLOBAL_DEFAULT_TIMEOUT而不是 None。

例如

import socket
...
def my_connect(timeout: float = socket._GLOBAL_DEFAULT_TIMEOUT):

这会导致隐式类型提示转换float为,Optional[float]如果该值显式None不出现,则正确地将参数键入为float. 这允许类型提示检查完全通过。


推荐阅读