Django 3.2 introduced two new methods: `sign_object` and
`unsign_object` which can sign/unsign "complex data structures" such as
lists, tuples, dictionaries:
https://docs.djangoproject.com/en/3.2/topics/signing/#django.core.signing.TimestampSigner
Because the methods take an arbitrary serializer (a JSON serializer by
default, but not guaranteed), we cannot be sure of the type of `obj`.
* Correct the type of FileField.storage
This instance property can't be a callable. Although the FileField constructor
allows a callable, it is immediately resolved to an instance of Storage.
See: f5802a21c4/django/db/models/fields/files.py (L231-L235)
* Correct the type of FieldFile.storage
This instance property is copied directly from `FileField.storage` and should be
the same type.
See: f5802a21c4/django/db/models/fields/files.py (L21)
* Add failing test for relation to model inheriting `objects`
Fails with:
```
pytest_mypy_plugins.utils.TypecheckAssertionError: Invalid output:
Expected:
main:2: note: Revealed type is "myapp.models.MyUser*"
main:3: note: Revealed type is "myapp.models.MyUser*"
<45 (diff)
<45 (diff)
Actual:
main:2: note: Revealed type is "myapp.models.MyUser*"
main:3: note: Revealed type is "myapp.models.MyUser*"
main:6: error: "MyUser" has no attribute "book_set" (diff)
main:6: note: Revealed type is "Any" (diff)
main:7: error: "MyUser" has no attribute "article_set" (diff)
main:7: note: Revealed type is "Any" (diff)
```
* Make AddRelatedManagers look for "objects" on parent model
Previously, AddRelatedManagers would fail if a related model had inherited
its `objects` field from a parent class. This would result in missing
relation attributes. This is fixed by using `get()` instead of `names`;
the former searches the MRO for the symbol, whereas the latter only looks
for symbols declared directly on the class.
Needed, because `django-stubs-ext` generally has to specified as a
production dependency (to use the monkey patching). `django-stubs` does
have `typing-extensions` as a dependency, but it is often used only as a
dev dependency as it has not runtime functionality.
Resolves: https://github.com/typeddjango/django-stubs/issues/702
* Use `Sequence` instead of `Iterable` for `send_messages`.
According to the documentation
(https://docs.djangoproject.com/en/3.2/topics/email/#email-backends),
`email_messages` is a list. Using `Iterable` will make it hard for
subclasses to implement this method utilizing functions like `__len__`.
While this still allows subclasses to accept `Iterable`.
* Fix function signature of `authenticate` of `BaseBackend`.
1. BaseBackend no longer requires the username and password argument.
They were removed 3 years ago in the commit below when `BaseBackend` is added:
75337a6050
2. `request` is optional for `authenticate` method.
According to django documentation, the authenticate method does not
necessarily require the request object.
https://docs.djangoproject.com/en/3.2/topics/auth/default/#authenticating-users
* Tighten the type of `streaming_content` to `Iterator[bytes]`.
It is an iterator of a bytestring according to the documentation:
https://docs.djangoproject.com/en/3.2/ref/request-response/#django.http.StreamingHttpResponse.streaming_content
* Fix function signature of `django.contrib.staticfiles.serve`.
Since this `serve` function uses `django.views.static.serve` that
accepts `HttpRequest` as its first argument, it is more reasonable
to type it with `HttpRequest` instead of `WSGIRequest`.
Related:
https://github.com/django/django/blob/main/django/contrib/staticfiles/views.py#L39
* Fix `MyModel.objects.filter(...).my_method()`
* Fix regression: `MyModel.objects.filter(...).my_method()` no longer worked when using from_queryset
This also fixes the self-type of the copied-over methods of the manager generated by from_queryset.
Previously it was not parameterized by the model class, but used Any.
The handling of unbound types is not tested here as I have not been able to
find a way to create a test case for it. It has been manually tested
against an internal codebase.
* Remove unneeded defer.
This matches the actual implementation in Django, where it only attempts
to use the result of get_users() in a for loop, which allows for any
Iterable, and it provides a more flexible and idiomatic API for users
who subclass PasswordResetForm.