QuerySet
class no longer derives from Collection
(django-stubs 5.0.0)
#2095
intgr
announced in
Announcements
Replies: 1 comment
-
I understand it's the correct way to go. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Starting in django-stubs version 5.0.0, the
QuerySet
class is no longer compatible withCollection[T]
(PR: #1925). This can require some changes to your code, if you get errors like the following:The previous behavior was incorrect and could possibly cause bugs, because Python's runtime
isinstance(queryset, Collection)
check returnsFalse
, where type checkers previously assumedTrue
.QuerySet
class continues to derive fromIterable[T]
andSized
.Example issue
However, this will cause new type checker errors where a QuerySet is passed into a Collection-typed argument, e.g.
Solution 1: Iterable
In most cases functions only want to iterate over the collection. In these cases, it's simple to just replace
Collection
withIterable
Solution 2: SizedIterable
The
Collection
base class includes__len__()
method, but that is lost when usingIterable
. Thus if the called function wants to calllen(users)
as well as iterate over it, it's possible to define a new protocol (e.g.SizedIterable
) that ensures both are implemented.Solution 3: Union of concrete classes
Usually when
QuerySet
was downcast into aCollection
, it's because the code needs to handle mixed input of QuerySets as well as other types. It's also possible to use union types (|
operator) instead of abstract base classes in such cases.Other work-arounds
If the called function is not under your control and you cannot change its signature, but you know that the code works correctly, it's also possible to just override the type checker.
Also you can change the runtime behavior of your code to convert the results of a QuerySet into a list.
Beta Was this translation helpful? Give feedback.
All reactions