Reparametrize managers without explicit type parameters (#1169)

* Reparametrize managers without explicit type parameters

This extracts the reparametrization logic from #1030 in addition to
removing the codepath that copied methods from querysets to managers.
That code path seems to not be needed with this change.

* Use typevars from parent instead of base

* Use typevars from parent manager instead of base manager

This removes warnings when subclassing from something other than the
base manager class, where the typevar has been restricted.

* Remove unused imports

* Fix failed test

* Only reparametrize if generics are omitted

* Fix docstring

* Add test with disallow_any_generics=True

* Add an FAQ section and document disallow_any_generics behaviour
This commit is contained in:
Sigurd Ljødal
2022-10-03 20:36:45 +03:00
committed by GitHub
parent 946274bed8
commit dde0f2f876
10 changed files with 196 additions and 164 deletions
+30
View File
@@ -191,6 +191,36 @@ def use_my_model() -> int:
return foo.xyz # Gives an error
```
### Why am I getting incompatible return type errors on my custom managers?
If you declare your custom managers without generics and override built-in
methods you might see an error message about incompatible error messages,
something like this:
```python
from django.db import models
class MyManager(model.Manager):
def create(self, **kwargs) -> "MyModel":
pass
```
will cause this error message:
```
error: Return type "MyModel" of "create" incompatible with return type "_T" in supertype "BaseManager"
```
This is happening because the `Manager` class is generic, but without
specifying generics the built-in manager methods are expected to return the
generic type of the base manager, which is any model. To fix this issue you
should declare your manager with your model as the type variable:
```python
class MyManager(models.Manager["MyModel"]):
...
```
### How do I annotate cases where I called QuerySet.annotate?
Django-stubs provides a special type, `django_stubs_ext.WithAnnotations[Model]`, which indicates that the `Model` has