What specifically are you looking at that is making you think that request.user is of type AbstractBaseUser? (Are you using a custom user model?)
The code throughout the authentication middleware always assigns an instance of UserModel to user. (See ModelBackend.authenticate)
On my system, print(type(request.user)) gives <class 'django.utils.functional.SimpleLazyObject'> and print(request.user.__class__) gives either <class 'django.contrib.auth.models.AnonymousUser'> or <class 'django.contrib.auth.models.User'>, depending upon whether the user is authenticated or not.
<opinion>
I don’t use any typing in my code. I find it adds more visual clutter to the code than the value it provides. As a result, I don’t use any of the “typing-related” tools in my work environment.
(That Python does not require explicit typing, and provides “duck typing” as a fundamental principle, is one of the reasons I moved to using Python as my primary language of choice 20+ years ago. I have no desire to see Python move anywhere in the direction of Java.) </opinion>
This is correct - and shows one of the reasons why I’m not a fan of typing in Python.
Technically, not only can the user model be changed (using the AUTH_USER_MODEL setting), but this user model does not need to have any relationship with AbstractBaseUser. Also, if you have multiple authentication backends in your project, request.user can be different types based upon the backend.
This clearly gets into a much bigger philosophical debate than one little aspect of Django. I think (think) you may be in the minority, and that most python programmers are using pylance or mypy or something for static type checking.
But I could be wrong and your preference of relying on duck typing has certainly given me pause for thought.
All of that said, going back to my original question, would you say my idea of using an assert statement makes sense then?
user = request.user
if user.is_authenticated:
assert isinstance(user, User)
...
name = user.username
My thinking is that if for some bizarre reason user is not an instance of User, I want it to fail hard and early, before I’ve had a chance to do anything with that object. Thoughts?
I probably am, and that’s ok. I hold many opinions that probably put me in the minority in a number of different areas. Some of that is due to my background, and some due to the nature of most of the work I do. I learned a long time ago that I come to Django with a very different perspective.
Actually, I think I kind of addressed this in my previous response:
The entity, request.user, is whatever your authentication backend returns for the user being authenticated.
Applying that to this case:
The assert enforces a requirement that may not be necessarily correct within the context of this code.
If user is not an instance of User, you do get an error. But what if you want to deploy this in a project using a custom authentication backend that doesn’t use the standard django.auth.User model?
Or, what if it is deployed in a project that uses a custom User model without a username attribute, but names it User? In that case, it will pass the assert, but throw an error at name = user.username anyway.
But that line name = user.usernamewill work if user is something like MyCustomUser, if that class provides a username attribute or property.
So this brings me back around to a more basic question.
Do you really care whether request.user is an instance of a class named User? If so, why? (And if so, I would suggest that you’re better off making this test in middleware rather than scattered around multiple views.)
Or is your concern only that request.user provides the attributes and properties that the rest of this view requires?
Whether or not this question makes a difference depends upon the scope of usage of your code.
If this code is specific to one particular project in a given environment, then it probably doesn’t matter.
But if you’re building a library of code - even if it’s for your own personal use and not going to be shared outside your organization - then these are types of questions you would want to consider.