Python3 输入和 mypy 的意外可选行为

Unexpected Optional behavior with Python3 typing and mypy

我刚开始使用 typingmypy

在下面的代码块中,mypy 抱怨无法将 ret 分配给 None 因为 Incompatible types in assignment (expression has type "None", variable has type "Tuple[Connection, Cursor]") (python-mypy).

    def __connect__(self) -> Tuple[Optional[Tuple[Conn, Cursor]], Status]:
        """Establish DB connection."""
        if self.db_type is DB_Type.SQLITE:
            conn = sqlite3.connect(self.db_name)
            cur = conn.cursor()
            ret, status = (conn, cur), Status(Code.OK)
        else:
            ret, status = None, self.INVALID_STATUS    # mypy error 
        return ret, status

但我将 return 类型签名定义为 Optional[Tuple[Connection, Cursor],而不是 Tuple[Connection, Cursor]。因此,要么我忽略了某些东西,要么 mypy 静态分析存在局限性,对此可能有一些解决方法……非常感谢您的指点。

mypy 通过使用第一个赋值的类型作为变量的类型来处理无类型变量。 所以对同一个无类型变量有两个不同的赋值类型被认为是类型不匹配。例如:

$ cat test.py 
foo, bar = 1, 2
foo, bar = None, 2
$ mypy test.py 
test.py:2: error: Incompatible types in assignment (expression has type "None", variable has type "int")  [assignment]
Found 1 error in 1 file (checked 1 source file)

您的代码中也出现了同样的问题,尽管不太明显:ret 被分配了类型 Tuple[Connection, Cursor],但另一个分支正在将 None 分配给 ret . return 类型无关紧要。

一种解决方法是设置显式类型 ret: Optional[Tuple[Connection, Cursor]]