![](/img/trans.png)
[英]mypy complains Incompatible return value type (got “Optional[str]”, expected “str”) when a function can only return str
[英]How to deal with "incompatible type "Optional[str]"; expected "str""?
假设我有这样的代码结构
from __future__ import annotations
from typing import TypedDict
class ValDict(TypedDict):
something: str
a: A
class A:
def __init__(self, x: str) -> None:
if x and isinstance(x, str):
self.x = x
else:
raise ValueError("x has to be a non-empty string")
class B:
def __init__(self, something: str, a: A) -> None:
self.something = something
if isinstance(a, A):
self.a = a
else:
raise ValueError("a has to be of type A")
@classmethod
def from_dict(cls, stuff: ValDict) -> B:
something = stuff.get('something')
a = stuff.get('a')
return cls(something, a)
我在上面运行mypy
,我会收到 2 个错误
错误:“B”的参数 1 具有不兼容的类型“Optional[str]”; 预期的“海峡”
错误:“B”的参数 2 具有不兼容的类型“Optional[A]”; 预期“A”
错误非常明显:由于.get
也可以返回None
,我可能没有将正确的类型传递给from_dict
方法中的cls
调用。
我的问题是如何避免它。 对于这个论点something
我可能会修改为
something = stuff.get('something', '')
但我将如何处理a
的情况? 有任何想法吗?
我会完全放弃使用get
并直接访问密钥。 当然,这会引发KeyError
,但是如果您传入A
实例以外的任何内容,则 class 无论如何都无法正确初始化。
您可以使用 A 的“默认实例”,只要它不存在于stuff
中,但从您的B.__init__
来看,您似乎不需要默认参数。
所以方法会变成:
@classmethod
def from_dict(cls, stuff: ValDict) -> B:
something = stuff['something']
a = stuff['a']
return cls(something, a)
这样,可能会发生三件事:
stuff
具有正确的键和值-> B
已初始化stuff
没有正确的键-> KeyError
上的B.from_dict
stuff
有正确的键,但是键"a"
的值不是正确的类型-> B.__init__
上的ValueError
将默认值传递给 get() 可能会有所帮助。
something = stuff.get('something', '')
mypy 非常不信任,因此在传入参数之前对参数进行一些断言会有所帮助:
arg_1 = "something"
arg_2 = A()
assert isistance(arg_1, str)
assert isistance(arg_2, A)
# and call your code without linting failing with an incompatible type warning.
b = B(arg_1, arg_2)
编辑:我看到断言在 class 中,但是 mypy 希望在将它们传递给 class 之前确定类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.