diff --git a/mypy_django_plugin/main.py b/mypy_django_plugin/main.py index 7dc431e0c..9f56ed89c 100644 --- a/mypy_django_plugin/main.py +++ b/mypy_django_plugin/main.py @@ -3,7 +3,7 @@ from functools import partial from typing import Any, Callable, Dict, List, Optional, Tuple, Type -from mypy.build import PRI_MYPY +from mypy.build import PRI_HIGH, PRI_MYPY from mypy.modulefinder import mypy_path from mypy.nodes import MypyFile, TypeInfo from mypy.options import Options @@ -99,14 +99,14 @@ def _get_typeinfo_or_none(self, class_name: str) -> Optional[TypeInfo]: return sym.node return None - def _new_dependency(self, module: str) -> Tuple[int, str, int]: + def _new_dependency(self, module: str, priority: int = PRI_MYPY) -> Tuple[int, str, int]: fake_lineno = -1 - return (PRI_MYPY, module, fake_lineno) + return (priority, module, fake_lineno) def get_additional_deps(self, file: MypyFile) -> List[Tuple[int, str, int]]: # for settings if file.fullname == "django.conf" and self.django_context.django_settings_module: - return [self._new_dependency(self.django_context.django_settings_module)] + return [self._new_dependency(self.django_context.django_settings_module, PRI_HIGH)] # for values / values_list if file.fullname == "django.db.models": diff --git a/tests/typecheck/conf/test_settings.yml b/tests/typecheck/conf/test_settings.yml index b825c148f..2dcfbf8ad 100644 --- a/tests/typecheck/conf/test_settings.yml +++ b/tests/typecheck/conf/test_settings.yml @@ -1,22 +1,36 @@ - case: test_setting_circular_import main: | from myapp import lib - custom_settings: | - from myapp.lib import function_returning_int - - IMMEDIATE_VALUE = 123 - CIRCULAR_WITHOUT_HINT = function_returning_int() - CIRCULAR_WITH_HINT: int = function_returning_int() + mypy_config: | + [mypy.plugins.django-stubs] + django_settings_module = myapp.settings files: - path: myapp/__init__.py + - path: myapp/settings.py + content: | + from myapp.lib import function_returning_int, const_with_circular_import + + IMMEDIATE_VALUE = 123 + CIRCULAR_WITH_HINT: int = function_returning_int() + CIRCULAR_WITHOUT_HINT_FUNCTION = function_returning_int() + CIRCULAR_WITHOUT_HINT_CONST = const_with_circular_import - path: myapp/lib.py content: | - from django.conf import settings + from typing import TYPE_CHECKING + import django.conf + + settings = django.conf.settings def test() -> None: reveal_type(settings.IMMEDIATE_VALUE) # N: Revealed type is "builtins.int" - reveal_type(settings.CIRCULAR_WITHOUT_HINT) # E: Import cycle from Django settings module prevents type inference for 'CIRCULAR_WITHOUT_HINT' [misc] # N: Revealed type is "Any" reveal_type(settings.CIRCULAR_WITH_HINT) # N: Revealed type is "builtins.int" + reveal_type(settings.CIRCULAR_WITHOUT_HINT_FUNCTION) # E: Import cycle from Django settings module prevents type inference for 'CIRCULAR_WITHOUT_HINT_FUNCTION' [misc] # N: Revealed type is "Any" + reveal_type(settings.CIRCULAR_WITHOUT_HINT_CONST) # E: Import cycle from Django settings module prevents type inference for 'CIRCULAR_WITHOUT_HINT_CONST' [misc] # N: Revealed type is "Any" def function_returning_int() -> int: return 42 + + if TYPE_CHECKING: + const_with_circular_import = settings.IMMEDIATE_VALUE + else: + const_with_circular_import = 0