def typecheck_queryset_filter(ctx: MethodContext, django_context: DjangoContext) -> MypyType: # Expected formal arguments for filter methods are `*args` and `**kwargs`. We'll only typecheck # `**kwargs`, which means that `arg_names[1]` is what we're interested in. lookup_kwargs = ctx.arg_names[1] provided_lookup_types = ctx.arg_types[1] assert isinstance(ctx.type, Instance) if not ctx.type.args or not isinstance(ctx.type.args[0], Instance): return ctx.default_return_type model_cls_fullname = ctx.type.args[0].type.fullname model_cls = django_context.get_model_class_by_fullname(model_cls_fullname) if model_cls is None: return ctx.default_return_type for lookup_kwarg, provided_type in zip(lookup_kwargs, provided_lookup_types): if lookup_kwarg is None: continue if isinstance(provided_type, Instance) and provided_type.type.has_base( fullnames.COMBINABLE_EXPRESSION_FULLNAME): provided_type = resolve_combinable_type(provided_type, django_context) lookup_type: MypyType if is_annotated_model_fullname(model_cls_fullname): lookup_type = AnyType(TypeOfAny.implementation_artifact) else: lookup_type = django_context.resolve_lookup_expected_type( ctx, model_cls, lookup_kwarg) # Managers as provided_type is not supported yet if isinstance(provided_type, Instance) and helpers.has_any_of_bases( provided_type.type, (fullnames.MANAGER_CLASS_FULLNAME, fullnames.QUERYSET_CLASS_FULLNAME)): return ctx.default_return_type helpers.check_types_compatible( ctx, expected_type=lookup_type, actual_type=provided_type, error_message=f"Incompatible type for lookup {lookup_kwarg!r}:", ) return ctx.default_return_type
def transform_into_proper_return_type(ctx: FunctionContext, django_context: DjangoContext) -> MypyType: default_return_type = ctx.default_return_type assert isinstance(default_return_type, Instance) outer_model_info = helpers.get_typechecker_api(ctx).scope.active_class() if (outer_model_info is None or not helpers.is_model_subclass_info(outer_model_info, django_context)): return ctx.default_return_type assert isinstance(outer_model_info, TypeInfo) if helpers.has_any_of_bases(default_return_type.type, fullnames.RELATED_FIELDS_CLASSES): return fill_descriptor_types_for_related_field(ctx, django_context) if default_return_type.type.has_base(fullnames.ARRAY_FIELD_FULLNAME): return determine_type_of_array_field(ctx, django_context) return set_descriptor_types_for_field(ctx)
def typecheck_queryset_filter(ctx: MethodContext, django_context: DjangoContext) -> MypyType: lookup_kwargs = ctx.arg_names[1] provided_lookup_types = ctx.arg_types[1] assert isinstance(ctx.type, Instance) if not ctx.type.args or not isinstance(ctx.type.args[0], Instance): return ctx.default_return_type model_cls_fullname = ctx.type.args[0].type.fullname model_cls = django_context.get_model_class_by_fullname(model_cls_fullname) if model_cls is None: return ctx.default_return_type for lookup_kwarg, provided_type in zip(lookup_kwargs, provided_lookup_types): if lookup_kwarg is None: continue if isinstance(provided_type, Instance) and provided_type.type.has_base( "django.db.models.expressions.Combinable"): provided_type = resolve_combinable_type(provided_type, django_context) lookup_type: MypyType if is_annotated_model_fullname(model_cls_fullname): lookup_type = AnyType(TypeOfAny.implementation_artifact) else: lookup_type = django_context.resolve_lookup_expected_type( ctx, model_cls, lookup_kwarg) # Managers as provided_type is not supported yet if isinstance(provided_type, Instance) and helpers.has_any_of_bases( provided_type.type, (fullnames.MANAGER_CLASS_FULLNAME, fullnames.QUERYSET_CLASS_FULLNAME)): return ctx.default_return_type helpers.check_types_compatible( ctx, expected_type=lookup_type, actual_type=provided_type, error_message=f"Incompatible type for lookup {lookup_kwarg!r}:", ) return ctx.default_return_type