-
-
Notifications
You must be signed in to change notification settings - Fork 366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add type annotations #558
Comments
The work-in-progress can be found in this branch. Given the relatively low line count, I thought I would be able to annotate all of The following commits might be worth reviewing already, as they don't contain type annotations themselves, but are code cleanups necessary to make mypy accept the code:
|
I don't know yet when I'll have time to finish the annotations, but I'll submit the fixes as separate PRs, both to make sure they can be included sooner and to simplify the review of the annotations PR later. |
Hi! I was wondering whether you have made any progress on this? I would like to use types too. Can I help? |
@mthuurne both PR's you are mentioning are merged. Are you willing to take the further lead on typing? |
I'll pick it up again. I split off one cleanup that can already be applied: #591. |
Even more cleanups: #597, #598. I also updated the branch on top of the latest |
Type annotations isn't a job that has to be done in one haul but you are getting pretty far. By any change, is there a way to make smaller chunks out of the branch? |
Yes, there should be ways to carve it up into multiple PRs. I prefer to first annotate everything in a branch though before submitting the annotations themselves, as that can uncover mistakes made earlier. In particular, having the unit tests annotated functions as a consistency check for the annotations in the code under test. Something that might be possible to split off already is adding mypy to CI. I'll have a look at that later today. |
Can you open a draft PR from the annotations branch so we can stay in touch with your progres? If we first merge all the low hanging fruit we may split up the remaining issues into sub branches when needed. Played around with the generic tests of the |
I could do that, but I'm still force-pushing after squashing corrections, so that would make the PR rather messy. If you don't mind that, I'll create a draft PR. |
I made the PR to add mypy to CI: #601. I put several discussion points in the PR comment, mostly about how to handle various dependencies. |
I don't mind, notifications for drafts is opt-in isn't it? |
Yes, but I couldn't create a draft PR from the start: I didn't see any checkbox on the submission form and starting the title with "Draft:" like in GitLab didn't work. So if you want to skip notifications, you'll have to unsubscribe from the PR, I'm afraid. In any case, what I was worried about is that comments on changes would become orphans as new versions are force-pushed. |
With 4.5.0 released we can merge our more impactful changes 🎉 |
Another small cleanup that can be merged: #610. I'm still working on completing the annotations, but it's progressing more slowly as the low-hanging fruit has already been picked. PR #601 could already be reviewed and merged: it would at least ensure that new developments do not regress the type checking. |
I like your progress @mthuurne If you are running out of time or want to subdivide it into smaller issues we can merge it as is and take that as starting point. Just let me know. |
One thing to decide is how to deal with mixins in the test suite. Unfortunately, there is no good way to handle mixins in Python's typing system yet. The problem with mixins is that they have expectations on what is available on If there is only limited functionality used from the base class, I typically duplicate the annotation on the mixin, like the class SoftDeletableManagerMixin(Generic[ModelT]):
"""
Manager that limits the queryset by default to show only not removed
instances of model.
"""
_queryset_class = SoftDeletableQuerySet
_db: str | None
... If a lot of functionality is used from the base class, I typically give the mixin an explicit base class during type checking, but not at runtime: if TYPE_CHECKING:
MixinBase = TestCase
else:
MixinBase = object
class FieldTrackerMixin(MixinBase):
... This can become quite tricky though, as you have to be careful to not break the method resolution order during type checking. Also there is the django-stubs mypy plugin, which executes code while A full example of this is 869c6a6, where I had to do some code surgery to get the type annotation overrides and method resolution order correct. In the particular case of unit tests, the main reason why mixins require special attention is because I used the pytest What would be the preferred way forward:
Personally I prefer the pytest style even when not dealing with mixins, but I can't speak for all developers who will work on this code in the future. |
Another small cleanup: #611. This one is backwards incompatible, but that means now is a good time to do that, right? |
Yes, 5.0 will be full of breaking changes :) |
Note that #541 is still an open issue. For now, I'll annotate the current behavior and drop the "fix" I had for this issue, since it probably wasn't the right fix. |
The draft PR #603 passed CI checks for the first time. There is still work to do though:
|
Those last two bullets aren't required (anymore) from my perspective. |
Do you guys believe an extra pair of hands would help in closing this issue and releasing 5.x ? @foarsitter @mthuurne |
The bulk of the work has been done: everything is covered in annotations. Now it just needs some verification and cleanups. Ways to help would be:
|
Note to anyone testing the new annotations: do not use Using just |
If we are in the testing phase I would like to release a beta, what do you people think? |
I agree @foarsitter , let's make a release candidate 🚀 . |
#603 is ready for merging into a beta / preview release. Some things to discuss before doing a production release: Use
|
Problem
When type-checking a model that uses
InheritanceManager
usingmypy
, the following error is displayed:According to this Stack Overflow post, the origin of this problem is the
django-stubs
mypy plugin being unable to findInheritanceManager
becausedjango-model-utils
does not provide type annotations.According to the linked post, no actual annotations are required, just a marker that the package is annotated. But I think real annotations would be good to have anyway, both for users and developers of
django-model-utils
.I am working on adding annotations to
django-model-utils
. I don't know if I'll have enough time to completely annotate it, but I'll share what I have in any case, probably tomorrow.Environment
django-stubs
1.16.0The text was updated successfully, but these errors were encountered: