diff --git a/mypy_django_plugin/django/context.py b/mypy_django_plugin/django/context.py index 2c041994b..a6ba3833f 100644 --- a/mypy_django_plugin/django/context.py +++ b/mypy_django_plugin/django/context.py @@ -384,6 +384,10 @@ def resolve_lookup_into_field( def resolve_lookup_expected_type(self, ctx: MethodContext, model_cls: Type[Model], lookup: str) -> MypyType: query = Query(model_cls) + if lookup == "pk" or lookup.startswith("pk__") and query.get_meta().pk is None: + # Primary key lookup when no primary key field is found, model is presumably + # abstract and we can't say anything about 'pk'. + return AnyType(TypeOfAny.implementation_artifact) try: lookup_parts, field_parts, is_expression = query.solve_lookup_type(lookup) if is_expression: diff --git a/tests/typecheck/models/test_abstract.yml b/tests/typecheck/models/test_abstract.yml new file mode 100644 index 000000000..e7303b5f1 --- /dev/null +++ b/tests/typecheck/models/test_abstract.yml @@ -0,0 +1,9 @@ +- case: test_filter_on_abstract_user_pk + main: | + from django.contrib.auth.models import AbstractUser + AbstractUser.objects.get(pk=1) + AbstractUser.objects.get(pk__in=[1]) + reveal_type(AbstractUser().pk) # N: Revealed type is "Any" + AbstractUser.objects.get(pkey=1) # ER: Cannot resolve keyword 'pkey' into field..* + installed_apps: + - django.contrib.auth