Skip to content

Commit

Permalink
Disable fallback to runtime types for Django settings
Browse files Browse the repository at this point in the history
This fallback to value.__class__ seems to be doing more harm than
good; see typeddjango#312 and typeddjango#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]>
  • Loading branch information
andersk committed Sep 24, 2022
1 parent 02999f3 commit 9a0e146
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 14 deletions.
2 changes: 1 addition & 1 deletion mypy_django_plugin/django/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def initialize_django(settings_module: str) -> Tuple["Apps", "LazySettings"]:
apps.get_swappable_settings_name.cache_clear() # type: ignore

if not settings.configured:
settings._setup()
settings._setup() # type: ignore

apps.populate(settings.INSTALLED_APPS)

Expand Down
22 changes: 9 additions & 13 deletions mypy_django_plugin/transformers/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ def get_user_model_hook(ctx: FunctionContext, django_context: DjangoContext) ->
def get_type_of_settings_attribute(ctx: AttributeContext, django_context: DjangoContext) -> MypyType:
assert isinstance(ctx.context, MemberExpr)
setting_name = ctx.context.name
if not hasattr(django_context.settings, setting_name):
ctx.api.fail(f"'Settings' object has no attribute {setting_name!r}", ctx.context)
return ctx.default_attr_type

typechecker_api = helpers.get_typechecker_api(ctx)

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

# if by any reason it isn't present there, get type from django settings
value = getattr(django_context.settings, setting_name)
value_fullname = helpers.get_class_fullname(value.__class__)

value_info = helpers.lookup_fully_qualified_typeinfo(typechecker_api, value_fullname)
if value_info is None:
return ctx.default_attr_type

return Instance(value_info, [])
ctx.api.fail(f"'Settings' object has no attribute {setting_name!r}", ctx.context)
return ctx.default_attr_type

0 comments on commit 9a0e146

Please sign in to comment.