From d9c851abcedf6a2a434da9a9dbda7aa536edce52 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Tue, 24 Nov 2020 13:38:03 +0200 Subject: [PATCH] Do not force django.contrib.* dependencies (#535) * Do not force django.contrib.* dependencies Fixes #428. Fixes #534. * Add one more test with contenttypes installed, but auth not --- mypy_django_plugin/django/context.py | 6 ++++-- mypy_django_plugin/transformers/request.py | 3 +++ tests/typecheck/test_request.yml | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/mypy_django_plugin/django/context.py b/mypy_django_plugin/django/context.py index 0c74b58..09c6e96 100644 --- a/mypy_django_plugin/django/context.py +++ b/mypy_django_plugin/django/context.py @@ -148,7 +148,9 @@ class DjangoContext: raise ValueError("No primary key defined") def get_expected_types(self, api: TypeChecker, model_cls: Type[Model], *, method: str) -> Dict[str, MypyType]: - from django.contrib.contenttypes.fields import GenericForeignKey + contenttypes_in_apps = self.apps_registry.is_installed("django.contrib.contenttypes") + if contenttypes_in_apps: + from django.contrib.contenttypes.fields import GenericForeignKey expected_types = {} # add pk if not abstract=True @@ -192,7 +194,7 @@ class DjangoContext: expected_types[field_name] = model_set_type - elif isinstance(field, GenericForeignKey): + elif contenttypes_in_apps and isinstance(field, GenericForeignKey): # it's generic, so cannot set specific model field_name = field.name gfk_info = helpers.lookup_class_typeinfo(api, field.__class__) diff --git a/mypy_django_plugin/transformers/request.py b/mypy_django_plugin/transformers/request.py index 83899ce..4132796 100644 --- a/mypy_django_plugin/transformers/request.py +++ b/mypy_django_plugin/transformers/request.py @@ -8,6 +8,9 @@ from mypy_django_plugin.lib import helpers def set_auth_user_model_as_type_for_request_user(ctx: AttributeContext, django_context: DjangoContext) -> MypyType: + if not django_context.apps_registry.is_installed("django.contrib.auth"): + return ctx.default_attr_type + # Imported here because django isn't properly loaded yet when module is loaded from django.contrib.auth.base_user import AbstractBaseUser from django.contrib.auth.models import AnonymousUser diff --git a/tests/typecheck/test_request.yml b/tests/typecheck/test_request.yml index 48a4ec7..080a225 100644 --- a/tests/typecheck/test_request.yml +++ b/tests/typecheck/test_request.yml @@ -27,6 +27,24 @@ reveal_type(request.user) # N: Revealed type is 'django.contrib.auth.models.User' custom_settings: | INSTALLED_APPS = ('django.contrib.contenttypes', 'django.contrib.auth') +- case: request_object_user_without_auth_and_contenttypes_apps + disable_cache: true + main: | + from django.http.request import HttpRequest + request = HttpRequest() + reveal_type(request.user) # N: Revealed type is 'Union[django.contrib.auth.base_user.AbstractBaseUser, django.contrib.auth.models.AnonymousUser]' + if request.user.is_authenticated: + reveal_type(request.user) # N: Revealed type is 'django.contrib.auth.base_user.AbstractBaseUser' +- case: request_object_user_without_auth_but_with_contenttypes_apps + disable_cache: true + main: | + from django.http.request import HttpRequest + request = HttpRequest() + reveal_type(request.user) # N: Revealed type is 'Union[django.contrib.auth.base_user.AbstractBaseUser, django.contrib.auth.models.AnonymousUser]' + if request.user.is_authenticated: + reveal_type(request.user) # N: Revealed type is 'django.contrib.auth.base_user.AbstractBaseUser' + custom_settings: | + INSTALLED_APPS = ('django.contrib.contenttypes',) - case: subclass_request_not_changed_user_type disable_cache: true main: |