Skip to content

Commit 92ef5d9

Browse files
kszmigielKacper Szmigiel
andauthored
additional defer() to offset the effect of using the type before decl… (#424)
* additional defer() to offset the effect of using the type before declaring * linter fix * linter fix * linter fix * test case Co-authored-by: Kacper Szmigiel <[email protected]>
1 parent f16d1b8 commit 92ef5d9

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

mypy_django_plugin/lib/helpers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ def copy_method_to_another_class(ctx: ClassDefContext, self_type: Instance,
343343
arguments = []
344344
bound_return_type = semanal_api.anal_type(method_type.ret_type,
345345
allow_placeholder=True)
346+
346347
assert bound_return_type is not None
347348

348349
if isinstance(bound_return_type, PlaceholderNode):
@@ -352,6 +353,10 @@ def copy_method_to_another_class(ctx: ClassDefContext, self_type: Instance,
352353
method_type.arg_types[1:],
353354
method_node.arguments[1:]):
354355
bound_arg_type = semanal_api.anal_type(arg_type, allow_placeholder=True)
356+
if bound_arg_type is None and not semanal_api.final_iteration:
357+
semanal_api.defer()
358+
return
359+
355360
assert bound_arg_type is not None
356361

357362
if isinstance(bound_arg_type, PlaceholderNode):

test-data/typecheck/managers/test_managers.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,3 +335,25 @@
335335
objects = MyManager()
336336
class ChildUser(models.Model):
337337
objects = MyManager()
338+
339+
- case: custom_manager_annotate_method_before_type_declaration
340+
main: |
341+
from myapp.models import ModelA, ModelB, ManagerA
342+
reveal_type(ModelA.objects) # N: Revealed type is 'myapp.models.ModelA_ManagerA1[myapp.models.ModelA]'
343+
reveal_type(ModelA.objects.do_something) # N: Revealed type is 'def (other_obj: myapp.models.ModelB) -> builtins.str'
344+
installed_apps:
345+
- myapp
346+
files:
347+
- path: myapp/__init__.py
348+
- path: myapp/models.py
349+
content: |
350+
from django.db import models
351+
class ManagerA(models.Manager):
352+
def do_something(self, other_obj: "ModelB") -> str:
353+
return 'test'
354+
class ModelA(models.Model):
355+
title = models.TextField()
356+
objects = ManagerA()
357+
class ModelB(models.Model):
358+
movie = models.TextField()
359+

0 commit comments

Comments
 (0)