改善
Kaizen  · Today I Learned by Ville Säävuori

Casting Types With MyPy

Typing in Python is not yet very mature. This small example displays several issues:

if request.user.is_authenticated:
    return JsonResponse(
        {
            "user": {
                "uid": request.user.uid,
                "username": request.user.username,
                "email": request.user.email,
            }
        }
    )

The original type of request.user is Union[AbstractBaseUser, AnonymousUser] (which itself is already wrong; the user is actually a Django model that inherits from AbstractBaseUser, not AbstractBaseUser). MyPy doesn’t understand that is_authenticated narrows the options, you need to do it manually using casting.

Here’s the final, working code:

if request.user.is_authenticated:
    user = cast(User, request.user)
    return JsonResponse(
        {
            "user": {
                "uid": user.uid,
                "username": user.username,
                "email": user.email,
            }
        }
    )