【发布时间】:2021-11-24 17:56:54
【问题描述】:
我有一个 testcase.py:
import pathlib
import typing as tp
# Not under my control
PathType = tp.Union[str, pathlib.Path]
def foreign(filename: PathType) -> PathType:
return filename
# Under my control
T = tp.TypeVar('T', str, pathlib.Path)
def my_func(filename: T) -> T:
return foreign(filename)
if __name__ == '__main__':
path1: str = '/abc/efg/string.py'
san_path1: str = my_func(path1)
print(san_path1, type(san_path1))
path2: pathlib.Path = pathlib.Path('/abc/efg/pathlib.py')
san_path2: pathlib.Path = my_func(path2)
print(san_path2, type(san_path2))
此文件中有两个部分。 在“不受我控制”部分中,我正在模拟不受我控制的模块的功能,但此功能的定义如下所示。
在“在我的控制下”部分,我试图强制执行,如果我用 str 调用 my_func 来取回 str,或者如果我用 pathlib.Path 调用 my_func 来取回 pathlib.Path,但要防止出现以下情况我将用 str 调用该函数并取回 pythlib.Path ,反之亦然。
代码运行良好。如果我运行它,输出是:
$ python testcase.py
/abc/efg/string.py <class 'str'>
/abc/efg/pathlib.py <class 'pathlib.PosixPath'>
但是 mypy 抱怨:
$ mypy testcase.py
testcase.py:17: error: Incompatible return value type (got "Union[str, Path]", expected "str")
testcase.py:17: error: Incompatible return value type (got "Union[str, Path]", expected "Path")
Found 2 errors in 1 file (checked 1 source file)
第 17 行是return foreign(filename)。
如何满足mypy?
【问题讨论】:
-
你能保证
foreign一定会为str和Path为Path返回str吗?这是作为 API 的一部分记录的,还是只是当前的行为?你能确定他们不会在不告诉你的情况下改变实施吗?他们可能正在使用Union,因为他们不想限制自己并打算稍后更改功能 -
对糟糕的标题投了反对票
-
我不能保证任何关于外国的,但我想确保 my_func 能像我解释的那样工作。如果他们改变外部功能,我的测试将失败,这没关系。请建议更好的标题。
-
如果你不能保证外部函数的实现,mypy 错误是正确的,你不能保证
my_func你想要的(除非你抛出无效类型的异常) -
很高兴建议一个标题,但首先我需要了解您的问题
标签: python generics type-hinting mypy python-typing