Skip to content

Commit

Permalink
add PlaceholderNode when deferring manager class hook (typeddjango#2228)
Browse files Browse the repository at this point in the history
  • Loading branch information
asottile authored and asottile-sentry committed Jul 22, 2024
1 parent 634fa60 commit 26d733a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
4 changes: 4 additions & 0 deletions mypy_django_plugin/transformers/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
MemberExpr,
Node,
OverloadedFuncDef,
PlaceholderNode,
RefExpr,
StrExpr,
SymbolTableNode,
Expand Down Expand Up @@ -317,6 +318,9 @@ def create_new_manager_class_from_from_queryset_method(ctx: DynamicClassDefConte
new_manager_info = create_manager_info_from_from_queryset_call(semanal_api, ctx.call, ctx.name)
if new_manager_info is None:
if not ctx.api.final_iteration:
# XXX: hack for python/mypy#17402
ph = PlaceholderNode(ctx.api.qualified_name(ctx.name), ctx.call, ctx.call.line, becomes_typeinfo=True)
ctx.api.add_symbol_table_node(ctx.name, SymbolTableNode(GDEF, ph))
ctx.api.defer()
return

Expand Down
35 changes: 35 additions & 0 deletions tests/typecheck/managers/querysets/test_from_queryset.yml
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,41 @@
self.ttl = ttl
super().__init__(*a, **k)
- case: test_from_queryset_with_deferral
main: |
from myapp.models import Concrete
reveal_type(Concrete.objects.qs_meth()) # N: Revealed type is "builtins.int"
reveal_type(Concrete.objects.manager_meth()) # N: Revealed type is "builtins.str"
mypy_config: |
[mypy.plugins.django-stubs]
django_settings_module = myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from typing import TypeVar, ClassVar
from typing_extensions import Self
from django.db import models
from django.db.models.manager import Manager
M = TypeVar("M", bound=models.Model, covariant=True)
# bogus forward-`metaclass=` to trigger second semanal pass similar to #2224
class CustomQuerySet(models.QuerySet[M], metaclass=MCS):
def qs_meth(self) -> int:
return 1
_base = Manager.from_queryset(CustomQuerySet)
class CustomBase(_base[M]):
def manager_meth(self) -> str:
return 'hi'
class Concrete(models.Model):
objects: ClassVar[CustomBase[Self]] = CustomBase()
class MCS(type): pass
- case: test_queryset_arg_as_unsupported_expressions
main: |
from typing import Union, Generic, TypeVar
Expand Down

0 comments on commit 26d733a

Please sign in to comment.