diff --git a/mypy_django_plugin/transformers/manytomany.py b/mypy_django_plugin/transformers/manytomany.py index 94ce58d8f..9d0f7d1a0 100644 --- a/mypy_django_plugin/transformers/manytomany.py +++ b/mypy_django_plugin/transformers/manytomany.py @@ -1,7 +1,7 @@ from typing import NamedTuple, Optional, Tuple, Union from mypy.checker import TypeChecker -from mypy.nodes import AssignmentStmt, Expression, MemberExpr, NameExpr, StrExpr, TypeInfo +from mypy.nodes import AssignmentStmt, Expression, MemberExpr, NameExpr, RefExpr, StrExpr, TypeInfo from mypy.plugin import FunctionContext, MethodContext from mypy.semanal import SemanticAnalyzer from mypy.types import Instance, ProperType, TypeVarType, UninhabitedType @@ -129,7 +129,7 @@ def get_model_from_expression( Attempts to resolve an expression to a 'TypeInfo' instance. Any lazy reference argument(e.g. "<app_label>.<object_name>") to a Django model is also attempted. """ - if isinstance(expr, NameExpr) and isinstance(expr.node, TypeInfo): + if isinstance(expr, RefExpr) and isinstance(expr.node, TypeInfo): if helpers.is_model_type(expr.node): return Instance(expr.node, []) diff --git a/tests/typecheck/fields/test_related.yml b/tests/typecheck/fields/test_related.yml index a800b5525..4ef7101d5 100644 --- a/tests/typecheck/fields/test_related.yml +++ b/tests/typecheck/fields/test_related.yml @@ -1340,3 +1340,36 @@ class MyModel(ConcreteParent, AbstractParent): m2m_5 = models.ManyToManyField(Other, related_name="mymodel") + +- case: test_m2m_related_managers_supports_renamed_imports + main: | + from myapp.models import MyModel + from other.models import Other + reveal_type(MyModel.m2m_1.through.objects) # N: Revealed type is "django.db.models.manager.Manager[myapp.models.MyModel_m2m_1]" + reveal_type(Other.auto_through.through.objects) # N: Revealed type is "django.db.models.manager.Manager[myapp.models.MyModel_m2m_1]" + reveal_type(MyModel.m2m_2.through.objects) # N: Revealed type is "django.db.models.manager.Manager[myapp.models.Through]" + reveal_type(Other.custom_through.through.objects) # N: Revealed type is "django.db.models.manager.Manager[myapp.models.Through]" + installed_apps: + - other + - myapp + files: + - path: other/__init__.py + - path: other/models.py + content: | + from django.db import models + + class Other(models.Model): + ... + - path: myapp/__init__.py + - path: myapp/models.py + content: | + from django.db import models + from other import models as other_models + + class Through(models.Model): + mymodel = models.ForeignKey("myapp.MyModel", on_delete=models.CASCADE) + other = models.ForeignKey(other_models.Other, on_delete=models.CASCADE) + + class MyModel(models.Model): + m2m_1 = models.ManyToManyField(other_models.Other, related_name="auto_through") + m2m_2 = models.ManyToManyField(other_models.Other, related_name="custom_through", through=Through)