def return_proper_field_type_from_get_field( ctx: MethodContext, django_context: DjangoContext) -> MypyType: # Options instance assert isinstance(ctx.type, Instance) model_type = ctx.type.args[0] if not isinstance(model_type, Instance): return _get_field_instance(ctx, fullnames.FIELD_FULLNAME) model_cls = django_context.get_model_class_by_fullname( model_type.type.fullname()) if model_cls is None: return _get_field_instance(ctx, fullnames.FIELD_FULLNAME) field_name_expr = helpers.get_call_argument_by_name(ctx, 'field_name') if field_name_expr is None: return _get_field_instance(ctx, fullnames.FIELD_FULLNAME) field_name = helpers.resolve_string_attribute_value( field_name_expr, ctx, django_context) if field_name is None: return _get_field_instance(ctx, fullnames.FIELD_FULLNAME) try: field = model_cls._meta.get_field(field_name) except FieldDoesNotExist as exc: ctx.api.fail(exc.args[0], ctx.context) return AnyType(TypeOfAny.from_error) field_fullname = helpers.get_class_fullname(field.__class__) return _get_field_instance(ctx, field_fullname)
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) default_return_type = get_proper_type(ctx.default_return_type) assert isinstance(default_return_type, Instance) model_type = _extract_model_type_from_queryset(ctx.type) if model_type is None: return AnyType(TypeOfAny.from_omitted_generics) model_cls = django_context.get_model_class_by_fullname( model_type.type.fullname) if model_cls is None: return default_return_type flat_expr = helpers.get_call_argument_by_name(ctx, "flat") if flat_expr is not None and isinstance(flat_expr, NameExpr): flat = helpers.parse_bool(flat_expr) else: flat = False named_expr = helpers.get_call_argument_by_name(ctx, "named") if named_expr is not None and isinstance(named_expr, NameExpr): named = helpers.parse_bool(named_expr) else: named = False if flat and named: ctx.api.fail("'flat' and 'named' can't be used together", ctx.context) return helpers.reparametrize_instance( default_return_type, [model_type, AnyType(TypeOfAny.from_error)]) # account for possible None flat = flat or False named = named or False is_annotated = is_annotated_model_fullname(model_type.type.fullname) row_type = get_values_list_row_type(ctx, django_context, model_cls, is_annotated=is_annotated, flat=flat, named=named) return helpers.reparametrize_instance(default_return_type, [model_type, row_type])
def set_descriptor_types_for_field(ctx: FunctionContext) -> Instance: default_return_type = cast(Instance, ctx.default_return_type) is_nullable = False null_expr = helpers.get_call_argument_by_name(ctx, 'null') if null_expr is not None: is_nullable = helpers.parse_bool(null_expr) or False set_type, get_type = get_field_descriptor_types(default_return_type.type, is_nullable) return helpers.reparametrize_instance(default_return_type, [set_type, get_type])
def set_descriptor_types_for_field(ctx: FunctionContext, *, is_set_nullable: bool = False, is_get_nullable: bool = False) -> Instance: default_return_type = cast(Instance, ctx.default_return_type) is_nullable = False null_expr = helpers.get_call_argument_by_name(ctx, "null") if null_expr is not None: is_nullable = helpers.parse_bool(null_expr) or False # Allow setting field value to `None` when a field is primary key and has a default that can produce a value default_expr = helpers.get_call_argument_by_name(ctx, "default") primary_key_expr = helpers.get_call_argument_by_name(ctx, "primary_key") if default_expr is not None and primary_key_expr is not None: is_set_nullable = helpers.parse_bool(primary_key_expr) or False set_type, get_type = get_field_descriptor_types( default_return_type.type, is_set_nullable=is_set_nullable or is_nullable, is_get_nullable=is_get_nullable or is_nullable, ) return helpers.reparametrize_instance(default_return_type, [set_type, get_type])
def return_proper_field_type_from_get_field( ctx: MethodContext, django_context: DjangoContext) -> MypyType: # Options instance assert isinstance(ctx.type, Instance) # bail if list of generic params is empty if len(ctx.type.args) == 0: return ctx.default_return_type model_type = ctx.type.args[0] if not isinstance(model_type, Instance): return ctx.default_return_type model_cls = django_context.get_model_class_by_fullname( model_type.type.fullname) if model_cls is None: return ctx.default_return_type field_name_expr = helpers.get_call_argument_by_name(ctx, 'field_name') if field_name_expr is None: return ctx.default_return_type field_name = helpers.resolve_string_attribute_value( field_name_expr, django_context) if field_name is None: return ctx.default_return_type try: field = model_cls._meta.get_field(field_name) except FieldDoesNotExist as exc: # if model is abstract, do not raise exception, skip false positives if not model_cls._meta.abstract: ctx.api.fail(exc.args[0], ctx.context) return AnyType(TypeOfAny.from_error) field_fullname = helpers.get_class_fullname(field.__class__) return _get_field_instance(ctx, field_fullname)