Skip to content

Commit 9a0e146

Browse files
committed
Disable fallback to runtime types for Django settings
This fallback to value.__class__ seems to be doing more harm than good; see #312 and #1162. Replace it with a clear error message that suggests a way to fix the problem rather than incompletely papering over it. Signed-off-by: Anders Kaseorg <[email protected]>
1 parent 02999f3 commit 9a0e146

File tree

2 files changed

+10
-14
lines changed

2 files changed

+10
-14
lines changed

mypy_django_plugin/django/context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def initialize_django(settings_module: str) -> Tuple["Apps", "LazySettings"]:
6262
apps.get_swappable_settings_name.cache_clear() # type: ignore
6363

6464
if not settings.configured:
65-
settings._setup()
65+
settings._setup() # type: ignore
6666

6767
apps.populate(settings.INSTALLED_APPS)
6868

mypy_django_plugin/transformers/settings.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ def get_user_model_hook(ctx: FunctionContext, django_context: DjangoContext) ->
2323
def get_type_of_settings_attribute(ctx: AttributeContext, django_context: DjangoContext) -> MypyType:
2424
assert isinstance(ctx.context, MemberExpr)
2525
setting_name = ctx.context.name
26-
if not hasattr(django_context.settings, setting_name):
27-
ctx.api.fail(f"'Settings' object has no attribute {setting_name!r}", ctx.context)
28-
return ctx.default_attr_type
2926

3027
typechecker_api = helpers.get_typechecker_api(ctx)
3128

@@ -35,15 +32,14 @@ def get_type_of_settings_attribute(ctx: AttributeContext, django_context: Django
3532
for module in [settings_module, global_settings_module]:
3633
if module is not None:
3734
sym = module.names.get(setting_name)
38-
if sym is not None and sym.type is not None:
35+
if sym is not None:
36+
if sym.type is None:
37+
ctx.api.fail(
38+
f"Import cycle from Django settings module prevents type inference for {setting_name!r}",
39+
ctx.context,
40+
)
41+
return ctx.default_attr_type
3942
return sym.type
4043

41-
# if by any reason it isn't present there, get type from django settings
42-
value = getattr(django_context.settings, setting_name)
43-
value_fullname = helpers.get_class_fullname(value.__class__)
44-
45-
value_info = helpers.lookup_fully_qualified_typeinfo(typechecker_api, value_fullname)
46-
if value_info is None:
47-
return ctx.default_attr_type
48-
49-
return Instance(value_info, [])
44+
ctx.api.fail(f"'Settings' object has no attribute {setting_name!r}", ctx.context)
45+
return ctx.default_attr_type

0 commit comments

Comments
 (0)