Add typing for the extra methods on User.

Review Request #14286 — Created Jan. 3, 2025 and updated

Information

Review Board
release-7.1.x

Reviewers

We patch User with custom methods useful within Review Board. Since
this is just monkey-patching, we don't have a good way to convey the
presence of the methods for any code importing
django.contrib.auth.models.User.

To address this, we're now changing the way we do the patching. All the
methods now live on an object that gets mixed in to a new User class
when type-checking, but is otherwise assigned as normal at runtime.

It's still the same User object at runtime. The only impact is for
type checking. To benefit from this, going forward we'll want to import
reviewboard.accounts.models.User (AnonymousUser is also provided for
convenience). This will ensure our typed class is used for type hints.
This can be done incrementally as needed, and won't introduce any kind
of compatibility challenges.

It's worth noting that Django does have an ability to swap out the
User model with a custom one, but this doesn't get us what we need.
Anything importing the old User model will continue to get that model
and not ours, and would introduce significant compatibility challenges,
so it's not an option.

All unit tests pass.

Tested updating a few modules making use of these methods and seeing that
the typing was correct.

Summary ID
Add typing for the extra methods on User.
We patch `User` with custom methods useful within Review Board. Since this is just monkey-patching, we don't have a good way to convey the presence of the methods for any code importing `django.contrib.auth.models.User`. To address this, we're now changing the way we do the patching. All the methods now live on an object that gets mixed in to a new `User` class when type-checking, but is otherwise assigned as normal at runtime. It's still the same `User` object at runtime. The only impact is for type checking. To benefit from this, going forward we'll want to import `reviewboard.accounts.models.User` (`AnonymousUser` is also provided for convenience). This will ensure our typed class is used for type hints. This can be done incrementally as needed, and won't introduce any kind of compatibility challenges. It's worth noting that Django does have an ability to swap out the `User` model with a custom one, but this doesn't get us what we need. Anything importing the old `User` model will continue to get that model and not ours, and would introduce significant compatibility challenges, so it's not an option.
0483f8f7a0514e09d62311e60d290b587e445d52
Description From Last Updated

redefinition of unused 'User' from line 43 Column: 5 Error code: F811

reviewbotreviewbot
Checks run (1 failed, 1 succeeded)
flake8 failed.
JSHint passed.

flake8