fix: #1924 remove `__contains__` from `QuerySet`
I have made things!
Related issues
Please see fixes https://github.com/typeddjango/django-stubs/issues/1924
Imho there should be an abstract base type which will make it possible to use this. Currently, Mypy allows passing a QS into a Collection. Merging this will break this behavior.
class DjangoContainer(Reversible[_Row], Iterable[_Row], Sized):
pass
should be added. It behaves like a container but isnt one.
def myFunc(some_tings: DjangoContainer): ...
would allow to pass in a list with Model instances and a queryset.
You are entirely correct, QuerySet is not a Collection. In fact, it's not Reversible either!
In [16]: isinstance(qs, Collection) # ✅
Out[16]: False
In [17]: isinstance(qs, Iterable)
Out[17]: True
In [18]: isinstance(qs, Sized)
Out[18]: True
In [19]: isinstance(qs, Reversible) # ⚠️
Out[19]: False
We keep discovering significant inaccuracies that have been in django-stubs from nearly the beginning. 😅 Both of these date back to 2019.
- https://github.com/typeddjango/django-stubs/commit/f02050911fc5ec4125f9034d79f338329ca7cf75#diff-389fe7d7dcfb77ddaac87c1f3bdc196f3ef0ca33b8047c6638a15f3a3db21b56L124-R125
- https://github.com/typeddjango/django-stubs/commit/324b961d7464d7419e5886da9401a3f35481218d#diff-389fe7d7dcfb77ddaac87c1f3bdc196f3ef0ca33b8047c6638a15f3a3db21b56L49-R53
I tested this out. I'm downcasting QuerySet[x] to Collection[x] in lots of places in my projects. Typically in places where I want to accept both QuerySet[model] and list[model] as some parameter. So this causes a fair amount of churn.
Most places work fine with Iterable[x] as well, but in some places I want to use len() on the iterable. AFAIK there's currently no straightforward way to say Iterable[T] & Sized in the type sytem. I guess that may have been the motivation in making QuerySets Collection.
But there are other solutions:
- Define a custom
class SizedIterable(Iterable[T_co], Sized, Protocol)for those use cases. - Instead of
Collection[T], use the more explicitlist[T] | QuerySet[T]
Not a big deal.
Are you interested in creating another PR to remove Reversible too?