Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get mypy to recognize login_required decorator?

I have the following Django view:

@login_required
def view(request: HttpRequest) -> HttpResponse:
    if not request.user.some_attribute:
        return redirect("somewhere")
    return render(request, "template_name")

and a custom User model that has an attribute some_attribute.

I use mypy to enforce type checking, with this mypy.ini:

[mypy]
ignore_missing_imports = True
plugins = mypy_django_plugin.main

[mypy.plugins.django-stubs]
django_settings_module = [PROJECT NAME].settings

However, mypy errors with the following:

Item "AnonymousUser" of "Union[User, AnonymousUser]" has no attribute "some_attribute"

which makes sense because an anonymous user wouldn't have that attribute, but I have a login_required decorator, making AnonymousUsers impossible (it would be a User).

How do I tell mypy to ignore this, without using # type: ignore?

like image 424
etnguyen03 Avatar asked Nov 01 '25 08:11

etnguyen03


1 Answers

You can also subclass the HttpRequest and explicitly set the user field on your subclass to have the type explicitly defined as User instead of the default union pair, like so:

from django.http import HttpRequest
from my_user_app.models import MyUser

class AuthenticatedHttpRequest(HttpRequest):
    user: MyUser

Then, every time you want to use the login_required decorator, set the type hint of the request argument to your subclass (in this case it would be AuthenticatedHttpRequest) like so:

@login_required
def view(request: AuthenticatedHttpRequest) -> HttpResponse:
    if not request.user.some_attribute:
        return redirect("somewhere")
    return render(request, "template_name")

This method is specified as a recommended one in django-stubs readme file, which apparently you're using to source the Django skeletons for mypy.

like image 182
GwynBleidD Avatar answered Nov 03 '25 22:11

GwynBleidD



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!