Skip to content

Commit bb9b66e

Browse files
committed
Add regression test for #2373 repeated deferral scenario
Test ensures from_queryset handles forward-referenced metaclass correctly and PlaceholderNode is not re-added on each semantic analysis iteration.
1 parent a35fcbf commit bb9b66e

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

tests/typecheck/managers/querysets/test_from_queryset.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,3 +999,46 @@
999999
field = models.CharField()
10001000
b = models.ForeignKey(B, on_delete=models.CASCADE)
10011001
objects = Manager()
1002+
1003+
# Regression test for #2373: Ensure from_queryset handles repeated deferrals
1004+
# correctly. When create_manager_info_from_from_queryset_call returns None due
1005+
# to forward references, PlaceholderNode should only be added once, not on
1006+
# every iteration.
1007+
- case: test_from_queryset_repeated_deferral_with_forward_metaclass
1008+
main: |
1009+
from typing_extensions import reveal_type
1010+
from myapp.models import MyModel
1011+
reveal_type(MyModel.objects.custom_method())
1012+
out: |
1013+
main:3: error: Access to generic instance variables via class is ambiguous [misc]
1014+
main:3: note: Revealed type is "builtins.str"
1015+
mypy_config: |
1016+
[mypy.plugins.django-stubs]
1017+
django_settings_module = myapp
1018+
files:
1019+
- path: myapp/__init__.py
1020+
- path: myapp/models.py
1021+
content: |
1022+
from typing import TypeVar
1023+
from django.db import models
1024+
from django.db.models.manager import Manager
1025+
1026+
M = TypeVar("M", bound=models.Model, covariant=True)
1027+
1028+
# Forward reference to metaclass triggers deferral, causing
1029+
# create_manager_info_from_from_queryset_call to return None
1030+
# on initial passes. The fix ensures PlaceholderNode is not
1031+
# re-added on each iteration, preventing progress flag from
1032+
# being set repeatedly.
1033+
class CustomQuerySet(models.QuerySet[M], metaclass=ForwardMCS):
1034+
def custom_method(self) -> str:
1035+
return "test"
1036+
1037+
CustomManager = Manager.from_queryset(CustomQuerySet)
1038+
1039+
class MyModel(models.Model):
1040+
objects = CustomManager()
1041+
1042+
# Forward-referenced metaclass defined after use
1043+
class ForwardMCS(type):
1044+
pass

0 commit comments

Comments
 (0)