Repository: typeddjango/django-stubs

Issue:
[Question] What is an alternative to isinstance(obj, QuerySet)?
I've recently got 

> Parameterized generics cannot be used with class or instance checks

with `django-stubs==1.9.0` for `isinstance(obj, QuerySet)` when I run mypy over the code.

What is the recommended way to do it?
[Question] What is an alternative to isinstance(obj, QuerySet)?
I've recently got 

> Parameterized generics cannot be used with class or instance checks

with `django-stubs==1.9.0` for `isinstance(obj, QuerySet)` when I run mypy over the code.

What is the recommended way to do it?


Discussion:
This is because `QuerySet` is now `= _QuerySet[_T, _T]` from https://github.com/typeddjango/django-stubs/commit/cfd69c0acc4bb3c282cab4a411b014afe280d359#diff-389fe7d7dcfb77ddaac87c1f3bdc196f3ef0ca33b8047c6638a15f3a3db21b56R170

We can try to alias it as `QuerySet = _QuerySet` it should be the same thing, but without subscription.

@MT-Cash can you please try that?
From where should I import `_QuerySet`? 
You cannot import `_QuerySet`, because it is our only-in-stubs thing. You can send a Pr with the `[_T, _T]` removed from this line: https://github.com/typeddjango/django-stubs/commit/cfd69c0acc4bb3c282cab4a411b014afe280d359#diff-389fe7d7dcfb77ddaac87c1f3bdc196f3ef0ca33b8047c6638a15f3a3db21b56R170

It might help.
Kinda stumbled over the same issue and can confirm, that removing `[_T, _T]` solved it for me.

Created PR #794.
This is because `QuerySet` is now `= _QuerySet[_T, _T]` from https://github.com/typeddjango/django-stubs/commit/cfd69c0acc4bb3c282cab4a411b014afe280d359#diff-389fe7d7dcfb77ddaac87c1f3bdc196f3ef0ca33b8047c6638a15f3a3db21b56R170

We can try to alias it as `QuerySet = _QuerySet` it should be the same thing, but without subscription.

@MT-Cash can you please try that?
From where should I import `_QuerySet`? 
You cannot import `_QuerySet`, because it is our only-in-stubs thing. You can send a Pr with the `[_T, _T]` removed from this line: https://github.com/typeddjango/django-stubs/commit/cfd69c0acc4bb3c282cab4a411b014afe280d359#diff-389fe7d7dcfb77ddaac87c1f3bdc196f3ef0ca33b8047c6638a15f3a3db21b56R170

It might help.
Kinda stumbled over the same issue and can confirm, that removing `[_T, _T]` solved it for me.

Created PR #794.

Resolving patch:
diff --git a/django_stubs_ext/django_stubs_ext/__init__.py b/django_stubs_ext/django_stubs_ext/__init__.py
--- a/django_stubs_ext/django_stubs_ext/__init__.py
+++ b/django_stubs_ext/django_stubs_ext/__init__.py
@@ -1,3 +1,4 @@
+from .aliases import QuerySetAny as QuerySetAny
 from .aliases import StrOrPromise, StrPromise
 from .aliases import ValuesQuerySet as ValuesQuerySet
 from .annotations import Annotations as Annotations
@@ -7,6 +8,7 @@
 
 __all__ = [
     "monkeypatch",
+    "QuerySetAny",
     "ValuesQuerySet",
     "WithAnnotations",
     "Annotations",
diff --git a/django_stubs_ext/django_stubs_ext/aliases.py b/django_stubs_ext/django_stubs_ext/aliases.py
--- a/django_stubs_ext/django_stubs_ext/aliases.py
+++ b/django_stubs_ext/django_stubs_ext/aliases.py
@@ -1,16 +1,18 @@
 import typing
 
 if typing.TYPE_CHECKING:
-    from django.db.models.query import _T, _QuerySet, _Row
+    from django.db.models.query import _T, _QuerySet, _QuerySetAny, _Row
     from django.utils.functional import _StrOrPromise as StrOrPromise
     from django.utils.functional import _StrPromise as StrPromise
 
+    QuerySetAny = _QuerySetAny
     ValuesQuerySet = _QuerySet[_T, _Row]
 else:
     from django.db.models.query import QuerySet
     from django.utils.functional import Promise as StrPromise
 
+    QuerySetAny = QuerySet
     ValuesQuerySet = QuerySet
     StrOrPromise = typing.Union[str, StrPromise]
 
-__all__ = ["StrOrPromise", "StrPromise", "ValuesQuerySet"]
+__all__ = ["StrOrPromise", "StrPromise", "QuerySetAny", "ValuesQuerySet"]


Test patch:
diff --git a/tests/typecheck/managers/querysets/test_querysetany.yml b/tests/typecheck/managers/querysets/test_querysetany.yml
new file mode 100644
--- /dev/null
+++ b/tests/typecheck/managers/querysets/test_querysetany.yml
@@ -0,0 +1,45 @@
+- case: queryset_isinstance_check
+  main: |
+    from typing import Any
+    from django.db.models.query import QuerySet
+    from django_stubs_ext import QuerySetAny
+
+    def foo(q: QuerySet[Any]) -> None:
+      pass
+
+    def bar(q: QuerySetAny) -> None:
+      pass
+
+    def baz(obj: object) -> None:
+      if isinstance(obj, QuerySetAny):
+        reveal_type(obj)             # N: Revealed type is "django.db.models.query._QuerySet[Any, Any]"
+        foo(obj)
+        bar(obj)
+
+      if isinstance(obj, QuerySet):  # E: Parameterized generics cannot be used with class or instance checks
+        reveal_type(obj)             # N: Revealed type is "django.db.models.query._QuerySet[Any, Any]"
+        foo(obj)
+        bar(obj)
+- case: queryset_list
+  main: |
+    from typing import List
+    from django.db.models.query import QuerySet
+    from django_stubs_ext import QuerySetAny
+    from myapp.models import User, Book
+
+    def try_append(queryset_instance: QuerySetAny, queryset: QuerySet[User], queryset_book: QuerySet[Book]) -> None:
+      user_querysets: List[QuerySet[User]] = []
+      user_querysets.append(queryset_instance)
+      user_querysets.append(queryset)
+      user_querysets.append(queryset_book)  # E: Argument 1 to "append" of "list" has incompatible type "_QuerySet[Book, Book]"; expected "_QuerySet[User, User]"
+  installed_apps:
+    - myapp
+  files:
+    - path: myapp/__init__.py
+    - path: myapp/models.py
+      content: |
+        from django.db import models
+        class User(models.Model):
+          pass
+        class Book(models.Model):
+          pass