类型提示无法在装饰器中评估

时间:2018-12-18 18:17:45

标签: python python-3.x pycharm typehints

给出

class A:
    pass

class B:
    pass

如果我定义一个新的ACallback类型,它使用一个A的实例

from typing import Callable

ACallback = Callable[[A], None]

并定义一个接受B实例的函数

def b_callback(b: B):
    pass

如果我尝试在预期b_callback的地方使用ACallback,则会收到类型提示警告-符合预期。

def test(callback: ACallback):
    pass


test(the_callback)  # <-- "Expected type '(A) -> None', got '(b: B) -> None` instead

但是,如果我创建一个使用ACallback的装饰器

def test2(callback: ACallback):
    def decorate(f):
        def new_f(*args, **kwargs):
            return f(*args, **kwargs)
        return new_f
    return decorate

并传递不匹配的功能

@test2(the_callback)  # <-- No type hint errors
def decorator_test():
    pass

我没有看到任何类型提示警告。

问题:是由于...引起的类型提示警告不足

  • 类型提示错误?
  • Python类型提示限制吗?
  • PyCharm类型提示限制?
  • 还有什么?

1 个答案:

答案 0 :(得分:2)

这似乎是PyCharm中的错误(或“缺少功能”)。我尝试了这个程序:

import typing

ACallback = typing.Callable[[int], None]

def test2(callback: ACallback):
    def decorate(f):
        def new_f(*args, **kwargs):
            return f(*args, **kwargs)
        return new_f
    return decorate


def foo(s: str):
    pass


test2(foo)


@test2(foo)
def bar():
    pass

使用最新版本的mypy,结果为

decorated.py:17: error: Argument 1 to "test2" has incompatible type "Callable[[str], Any]"; expected "Callable[[int], None]"
decorated.py:20: error: Argument 1 to "test2" has incompatible type "Callable[[str], Any]"; expected "Callable[[int], None]"

即两种用法都导致错误。


如果要与PyCharm结合使用,请至少使用2个不同的插件进行PyCharm集成;一个名为mypy,另一个命名为Dropbox,即not available via JetBrains repository

all the key mypy/Python type hinting people are employed by Dropbox ...

的意义上,我将DropBox视为“官方的mypy认可的插件”。