您如何在超载中正确键入内部变量

发布于 2025-01-24 17:47:52 字数 1621 浏览 2 评论 0原文

我有一个Mypy不喜欢的过载函数,因为返回类型提示与推断类型发生冲突。

Incompatible return value type (got "List[Tuple[Union[TestFunc, ScriptFunc], TestDocInfo]]", 
expected "Union[List[Tuple[TestFunc, TestDocInfo]], List[Tuple[ScriptFunc, TestDocInfo]]]")

我知道为什么推断的类型是不同的。我不知道该怎么办。

是否有一些方法可以提示使用类似的超载时fn

from __future__ import annotations
from typing import List, Type, Union, Tuple, overload
from types import ModuleType

def parse_test_doc_info(fn: Union[TestFunc, ScriptFunc]) -> TestDocInfo:
    ...

class TestDocInfo:
    ...

class TestFunc:
    ...

class ScriptFunc:
    ...

class TestPrefix:
    pat = "test_"

class ScriptPrefix:
    pat = "script_"

T_LT = List[Tuple[TestFunc, TestDocInfo]]
T_LS = List[Tuple[ScriptFunc, TestDocInfo]]

@overload
def foo(module: ModuleType, prefix: Type[TestPrefix] = ...) -> T_LT:
    ...

@overload
def foo(module: ModuleType, prefix: Type[ScriptPrefix]) -> T_LS:
    ...

def foo(module: ModuleType, 
        prefix: Union[Type[TestPrefix], Type[ScriptPrefix]] = TestPrefix
) -> Union[T_LT, T_LS]:
    test_or_script_functions = []
    for name, obj in module.__dict__.items():
        if name.startswith(prefix.pat):
            if callable(obj):
                fn: Union[TestFunc, ScriptFunc] = obj
                # ^ how do you type hint fn without conflicting with return type?
                info: TestDocInfo = parse_test_doc_info(fn)
                test_or_script_functions.append((fn, info))
    return test_or_script_functions  # <-- mypy errors on this

I have a overload function that mypy doesn't like because the return type hint conflicts with the inferred type.

Incompatible return value type (got "List[Tuple[Union[TestFunc, ScriptFunc], TestDocInfo]]", 
expected "Union[List[Tuple[TestFunc, TestDocInfo]], List[Tuple[ScriptFunc, TestDocInfo]]]")

I understand why the inferred type is different. I don't know what to do about it.

Is there some way to hint what fn when using an overload like this?

from __future__ import annotations
from typing import List, Type, Union, Tuple, overload
from types import ModuleType

def parse_test_doc_info(fn: Union[TestFunc, ScriptFunc]) -> TestDocInfo:
    ...

class TestDocInfo:
    ...

class TestFunc:
    ...

class ScriptFunc:
    ...

class TestPrefix:
    pat = "test_"

class ScriptPrefix:
    pat = "script_"

T_LT = List[Tuple[TestFunc, TestDocInfo]]
T_LS = List[Tuple[ScriptFunc, TestDocInfo]]

@overload
def foo(module: ModuleType, prefix: Type[TestPrefix] = ...) -> T_LT:
    ...

@overload
def foo(module: ModuleType, prefix: Type[ScriptPrefix]) -> T_LS:
    ...

def foo(module: ModuleType, 
        prefix: Union[Type[TestPrefix], Type[ScriptPrefix]] = TestPrefix
) -> Union[T_LT, T_LS]:
    test_or_script_functions = []
    for name, obj in module.__dict__.items():
        if name.startswith(prefix.pat):
            if callable(obj):
                fn: Union[TestFunc, ScriptFunc] = obj
                # ^ how do you type hint fn without conflicting with return type?
                info: TestDocInfo = parse_test_doc_info(fn)
                test_or_script_functions.append((fn, info))
    return test_or_script_functions  # <-- mypy errors on this

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

彩虹直至黑白 2025-01-31 17:47:52

而不是foo返回union [t_lt,t_ls]您可以使其返回list [tuple [union [testfunc,scriptfunc],testDocinfo],testDocinfo]> :

T_LT = List[Tuple[TestFunc, TestDocInfo]]
T_LS = List[Tuple[ScriptFunc, TestDocInfo]]
T_LTS = List[Tuple[Union[TestFunc, ScriptFunc], TestDocInfo]]

@overload
def foo(module: ModuleType, prefix: Type[TestPrefix] = ...) -> T_LT:
    ...

@overload
def foo(module: ModuleType, prefix: Type[ScriptPrefix]) -> T_LS:
    ...

def foo(module: ModuleType, 
        prefix: Union[Type[TestPrefix], Type[ScriptPrefix]] = TestPrefix
) -> T_LTS:
    test_or_script_functions = []
    for name, obj in module.__dict__.items():
        if name.startswith(prefix.pat):
            if callable(obj):
                fn: Union[TestFunc, ScriptFunc] = obj
                info: TestDocInfo = parse_test_doc_info(fn)
                test_or_script_functions.append((fn, info))
    return test_or_script_functions

或者您可以提示test_or_script_functions与您进行返回的方式相同:

test_or_script_functions: Union[T_LT, T_LS]

但是,只有通过仅更改fn的提示,就没有一种方法来解决它

Instead of foo returning Union[T_LT, T_LS] you can make it return List[Tuple[Union[TestFunc, ScriptFunc], TestDocInfo]]:

T_LT = List[Tuple[TestFunc, TestDocInfo]]
T_LS = List[Tuple[ScriptFunc, TestDocInfo]]
T_LTS = List[Tuple[Union[TestFunc, ScriptFunc], TestDocInfo]]

@overload
def foo(module: ModuleType, prefix: Type[TestPrefix] = ...) -> T_LT:
    ...

@overload
def foo(module: ModuleType, prefix: Type[ScriptPrefix]) -> T_LS:
    ...

def foo(module: ModuleType, 
        prefix: Union[Type[TestPrefix], Type[ScriptPrefix]] = TestPrefix
) -> T_LTS:
    test_or_script_functions = []
    for name, obj in module.__dict__.items():
        if name.startswith(prefix.pat):
            if callable(obj):
                fn: Union[TestFunc, ScriptFunc] = obj
                info: TestDocInfo = parse_test_doc_info(fn)
                test_or_script_functions.append((fn, info))
    return test_or_script_functions

Or you could hint test_or_script_functions the same way you did the return:

test_or_script_functions: Union[T_LT, T_LS]

But a don't think there's a way to solve it by only changing fn's hint

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文