Exemplo n.º 1
0
    def resolve_lookup_into_field(self, model_cls: Type[Model], lookup: str) -> Union[Field, ForeignObjectRel]:
        query = Query(model_cls)
        lookup_parts, field_parts, is_expression = query.solve_lookup_type(lookup)
        if lookup_parts:
            raise LookupsAreUnsupported()

        return self._resolve_field_from_parts(field_parts, model_cls)
Exemplo n.º 2
0
    def resolve_lookup(self, model_cls: Type[Model], lookup: str) -> Field:
        query = Query(model_cls)
        lookup_parts, field_parts, is_expression = query.solve_lookup_type(
            lookup)
        if lookup_parts:
            raise FieldError('Lookups not supported yet')

        currently_observed_model = model_cls
        current_field = None
        for field_part in field_parts:
            if field_part == 'pk':
                return self.django_context.get_primary_key_field(
                    currently_observed_model)

            current_field = currently_observed_model._meta.get_field(
                field_part)
            if not isinstance(current_field, (ForeignObjectRel, RelatedField)):
                continue

            currently_observed_model = self.django_context.fields_context.get_related_model_cls(
                current_field)
            if isinstance(current_field, ForeignObjectRel):
                current_field = self.django_context.get_primary_key_field(
                    currently_observed_model)

        # if it is None, solve_lookup_type() will fail earlier
        assert current_field is not None
        return current_field
Exemplo n.º 3
0
    def resolve_lookup_expected_type(self, ctx: MethodContext,
                                     model_cls: Type[Model],
                                     lookup: str) -> MypyType:
        query = Query(model_cls)
        try:
            lookup_parts, field_parts, is_expression = query.solve_lookup_type(
                lookup)
            if is_expression:
                return AnyType(TypeOfAny.explicit)
        except FieldError as exc:
            ctx.api.fail(exc.args[0], ctx.context)
            return AnyType(TypeOfAny.from_error)

        field = self._resolve_field_from_parts(field_parts, model_cls)

        lookup_cls = None
        if lookup_parts:
            lookup = lookup_parts[-1]
            lookup_cls = field.get_lookup(lookup)
            if lookup_cls is None:
                # unknown lookup
                return AnyType(TypeOfAny.explicit)

        if lookup_cls is None or isinstance(lookup_cls, Exact):
            return self.get_field_lookup_exact_type(
                helpers.get_typechecker_api(ctx), field)

        assert lookup_cls is not None

        lookup_info = helpers.lookup_class_typeinfo(
            helpers.get_typechecker_api(ctx), lookup_cls)
        if lookup_info is None:
            return AnyType(TypeOfAny.explicit)

        for lookup_base in helpers.iter_bases(lookup_info):
            if lookup_base.args and isinstance(lookup_base.args[0], Instance):
                lookup_type: MypyType = lookup_base.args[0]
                # if it's Field, consider lookup_type a __get__ of current field
                if (isinstance(lookup_type, Instance)
                        and lookup_type.type.fullname()
                        == fullnames.FIELD_FULLNAME):
                    field_info = helpers.lookup_class_typeinfo(
                        helpers.get_typechecker_api(ctx), field.__class__)
                    if field_info is None:
                        return AnyType(TypeOfAny.explicit)
                    lookup_type = helpers.get_private_descriptor_type(
                        field_info,
                        '_pyi_private_get_type',
                        is_nullable=field.null)
                return lookup_type

        return AnyType(TypeOfAny.explicit)