我如何告诉 MyPy 参数不是可选的?

How do I tell MyPy that a parameter is not optional?

我有一个对象 src 和一个可选对象 dest。如果 dest 未传递到函数中,则会创建一个新的 MyObj 并将其传递给另一个函数。

使用 mypy==0.610 这给了我:

error: Argument 2 to "copy_data" has incompatible type "Optional[MyObj]"; expected "MyObj"

如何告诉 MyPy destcopy_data 函数中不是可选的?

from typing import Optional


class MyObj(object):
    def __init__(self, name):
        self.name = name

def new_obj(name):
    # type (str) -> MyObj
    return MyObj(name=name)

def copy_stuff(src, dest=None, fname=None):
    # type: (MyObj, Optional[MyObj], Optional[str]) -> MyObj
    if not dest:
        dest = new_obj(fname)
    my_obj = copy_data(src, dest)
    return my_obj

def copy_data(src, dest):
    # type: (MyObj, MyObj) -> MyObj
    return dest

这里的错误在new_obj。您在类型注释中缺少一个冒号。我通过在你的 MVE 中放入一些 reveal_types 来解决这个问题:

def new_obj(name):
    # type (str) -> MyObj
    #     ^ ERROR is here
    return MyObj(name=name)

def copy_stuff(src, dest=None, fname=None):
    # type: (MyObj, Optional[MyObj], Optional[str]) -> MyObj
    reveal_type(new_obj)  # E: Revealed type is 'def (name: Any) -> Any'
    if not dest:
        reveal_type(dest)  # Optional[MyObj]
        dest = new_obj(fname)
        reveal_type(dest)  # Optional[MyObj]
    my_obj = copy_data(src, dest)
    return my_obj

Mypy 在从返回 Any 的函数分配时似乎保留类型 Optional[MyObj]。固定类型注释后,它按预期工作。