当类型实际上正确时如何修复 MyPy [返回值] 错误

问题描述 投票:0回答:1

我正在使用 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
python django mypy python-typing django-ninja
1个回答
0
投票

您需要明确告诉 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
© www.soinside.com 2019 - 2024. All rights reserved.