我正在使用 Django-Ninja + MyPy,我收到此错误,它收到的类型为 tuple[int, dict[str, str]]" 不正确,因为它与 tuple[int, None 之一不匹配] | tuple[int, DetailType] 类型,但它与第二种类型完全相同,因为在代码的其他部分,它可以正确地计算出它具有 "detail" 。但一旦我使用 Union[...] 它就无法递归地查找?
apps/users/views.py:106: error: Incompatible return value type (got "tuple[int, Message]", expected "tuple[int, None] | tuple[int, DetailType]") [return-value]
这就是我的类型的样子:
DetailType = TypedDict("DetailType", {"detail": str})
MessageType = tuple[int, DetailType]
NoContentType = tuple[int, None]
这是 mypy 返回错误的完整代码:
@post("me/password/change/", response={204: None, 401: Message}, url_name="users_me_password_change")
def change_password(request: HttpRequest, data: ChangePasswordRequest) -> Union[NoContentType, MessageType]: <<< THIS IS RETURN TYPE
user = request.user
if not user.check_password(data.password):
return 401, {"detail": "Password is incorrect."} <<< IN THIS LINE IS MYPY ERROR
user.set_password(data.new_password)
user.save()
return 204, None
您需要明确告诉 MyPy 您的
MessageType
是一个带有整数状态代码和 DetailType
的元组,其中 DetailType
是 TypedDict
。但是,当您直接在 return 语句中使用 dict[str, str]
时,就会出现问题,该语句不会自动识别为与您的 DetailType
兼容。
这是解决此问题的解决方案:
DetailType
。from typing import TypedDict, Union
# Define the types
DetailType = TypedDict("DetailType", {"detail": str})
MessageType = tuple[int, DetailType]
NoContentType = tuple[int, None]
# Define the function with the return type hint
@post("me/password/change/", response={204: None, 401: Message}, url_name="users_me_password_change")
def change_password(request: HttpRequest, data: ChangePasswordRequest) -> Union[NoContentType, MessageType]:
user = request.user
if not user.check_password(data.password):
# Use the correct MessageType here, which expects a dict[str, str] under "detail"
return 401, {"detail": "Password is incorrect."} # This should be fine now
user.set_password(data.new_password)
user.save()
return 204, None