Skip to content

Commit 997ac44

Browse files
authored
django-stubs-ext: Export RelatedManager, ManyRelatedManager stub-only classes (#1834)
RelatedManager, ManyRelatedManager classes are sometimes useful for type hinting. But these classes don't exist as is at Django runtime, rather they are defined inside function bodies. * When `TYPE_CHECKING`, we re-export django-stubs fake classes. * At runtime, we define these as `Protocol[_T]`. This has the advantage that Python prevents them being used with isinstance(). Usage before: ```python if TYPE_CHECKING: from django.db.models.manager import RelatedManager # before PR #1814 def get_manager() -> "RelatedManager[MyModel]": ... ``` Usage after: ```python from django_stubs_ext.db.models.manager import RelatedManager def get_manager() -> RelatedManager[MyModel]: ... ```
1 parent 965d88a commit 997ac44

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed
File renamed without changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from typing import TYPE_CHECKING
2+
3+
# Re-export stubs-only classes RelatedManger and ManyRelatedManager.
4+
# These are fake, Django defines these inside function body.
5+
if TYPE_CHECKING:
6+
# noinspection PyUnresolvedReferences
7+
from django.db.models.fields.related_descriptors import ManyRelatedManager as ManyRelatedManager
8+
9+
# noinspection PyUnresolvedReferences
10+
from django.db.models.fields.related_descriptors import RelatedManager as RelatedManager
11+
12+
else:
13+
from typing import Protocol, TypeVar
14+
15+
_T = TypeVar("_T")
16+
17+
# Define as `Protocol` to prevent them being used with `isinstance()`.
18+
# These actually inherit from `BaseManager`.
19+
class RelatedManager(Protocol[_T]):
20+
pass
21+
22+
class ManyRelatedManager(Protocol[_T]):
23+
pass

0 commit comments

Comments
 (0)