Skip to content

Commit

Permalink
Handle mismatching types in queryset method resolving gracefully (#1727)
Browse files Browse the repository at this point in the history
Replace a couple of asserts with if statements to avoid unnecessary
crashes.
  • Loading branch information
flaeppe authored Sep 22, 2023
1 parent 3c5a53e commit 5ba0b06
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 9 deletions.
8 changes: 5 additions & 3 deletions mypy_django_plugin/transformers/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from mypy.plugin import AnalyzeTypeContext, AttributeContext, CheckerPluginInterface, ClassDefContext
from mypy.plugins import common
from mypy.semanal import SemanticAnalyzer
from mypy.types import AnyType, Instance, LiteralType, TypedDictType, TypeOfAny, TypeType, get_proper_type
from mypy.types import AnyType, Instance, LiteralType, ProperType, TypedDictType, TypeOfAny, TypeType, get_proper_type
from mypy.types import Type as MypyType
from mypy.typevars import fill_typevars

Expand Down Expand Up @@ -775,7 +775,7 @@ def handle_annotated_type(ctx: AnalyzeTypeContext, django_context: DjangoContext

def get_or_create_annotated_type(
api: Union[SemanticAnalyzer, CheckerPluginInterface], model_type: Instance, fields_dict: Optional[TypedDictType]
) -> Instance:
) -> ProperType:
"""
Get or create the type for a model for which you getting/setting any attr is allowed.
Expand All @@ -800,7 +800,9 @@ def get_or_create_annotated_type(
cast(TypeChecker, api), model_module_name + "." + type_name
)
if annotated_typeinfo is None:
model_module_file = api.modules[model_module_name] # type: ignore
model_module_file = api.modules.get(model_module_name) # type: ignore
if model_module_file is None:
return AnyType(TypeOfAny.from_error)

if isinstance(api, SemanticAnalyzer):
annotated_model_type = api.named_type_or_none(ANY_ATTR_ALLOWED_CLASS_FULLNAME, [])
Expand Down
18 changes: 12 additions & 6 deletions mypy_django_plugin/transformers/querysets.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,11 @@ def get_values_list_row_type(

def extract_proper_type_queryset_values_list(ctx: MethodContext, django_context: DjangoContext) -> MypyType:
# called on the Instance, returns QuerySet of something
assert isinstance(ctx.type, Instance)
if not isinstance(ctx.type, Instance):
return ctx.default_return_type
default_return_type = get_proper_type(ctx.default_return_type)
assert isinstance(default_return_type, Instance)
if not isinstance(default_return_type, Instance):
return ctx.default_return_type

model_type = _extract_model_type_from_queryset(ctx.type)
if model_type is None:
Expand Down Expand Up @@ -205,9 +207,11 @@ def gather_kwargs(ctx: MethodContext) -> Optional[Dict[str, MypyType]]:

def extract_proper_type_queryset_annotate(ctx: MethodContext, django_context: DjangoContext) -> MypyType:
# called on the Instance, returns QuerySet of something
assert isinstance(ctx.type, Instance)
if not isinstance(ctx.type, Instance):
return ctx.default_return_type
default_return_type = get_proper_type(ctx.default_return_type)
assert isinstance(default_return_type, Instance)
if not isinstance(default_return_type, Instance):
return ctx.default_return_type

model_type = _extract_model_type_from_queryset(ctx.type)
if model_type is None:
Expand Down Expand Up @@ -270,9 +274,11 @@ def resolve_field_lookups(lookup_exprs: Sequence[Expression], django_context: Dj

def extract_proper_type_queryset_values(ctx: MethodContext, django_context: DjangoContext) -> MypyType:
# called on QuerySet, return QuerySet of something
assert isinstance(ctx.type, Instance)
if not isinstance(ctx.type, Instance):
return ctx.default_return_type
default_return_type = get_proper_type(ctx.default_return_type)
assert isinstance(default_return_type, Instance)
if not isinstance(default_return_type, Instance):
return ctx.default_return_type

model_type = _extract_model_type_from_queryset(ctx.type)
if model_type is None:
Expand Down

0 comments on commit 5ba0b06

Please sign in to comment.