django-stubs icon indicating copy to clipboard operation
django-stubs copied to clipboard

`filter` method on custom `QuerySet` raises "Unexpected keyword argument" error

Open ethanscorey opened this issue 3 years ago • 2 comments

Bug report

What's wrong

When I create a custom QuerySet subclass, mypy raises the following error: app.models.py:59: Unexpected keyword argument "name" for "filter" of "ItemManager"

My code looks like the following:

from django.db import models
from django.db.models.manager import BaseManager


class ItemQuerySet(models.QuerySet):
    ...


ItemManager = BaseManager.from_queryset(ItemQuerySet)


class Item:
    class Meta:
        base_manager_name = "objects"

    objects = ItemManager()
    name = models.CharField(max_length=200)
    parent = models.ForeignKey("Parent", on_delete=models.CASCADE)


class Parent:
    ...
    @property
    def foo(self) -> ItemQuerySet:
        return self.item_set.filter(name="foo")

How is that should be

Given that name is a defined field on the Item class, I shouldn't be getting any complaints from mypy. I tried changing ItemQuerySet to ItemQuerySet[Item] in my type annotation, but that just got me a different error ("ItemQuerySet" expects no type arguments, but 1 given).

Is there a workaround I'm missing? Or is this a bug?

System information

  • OS: Ubuntu 20.04.3 LTS (Focal Fossa)
  • python version: 3.10.2
  • django version: 4.0.2
  • mypy version: 0.931
  • django-stubs version: 1.9.0
  • django-stubs-ext version: 0.3.1

ethanscorey avatar Feb 06 '22 04:02 ethanscorey

One quick update: I did figure out how to get rid of the the "ItemQuerySet" expects no type arguments... error. I just needed to change the class declaration to the following:

ModelType = TypeVar("ModelType", bound="models.Model")


class ItemQuerySet(models.QuerySet, Generic[ModelType]):
    ...

But that still doesn't solve my problem. I'm still getting Unexpected keyword argument "name" for "filter" of "ItemManager"

ethanscorey avatar Feb 06 '22 17:02 ethanscorey

What happens if you do this?

class ItemQuerySet(models.QuerySet["Item"]):
    ...

flaeppe avatar Jun 17 '22 11:06 flaeppe