Esempio n. 1
0
def determine_model_cls_from_string_for_migrations(ctx: MethodContext) -> Type:
    app_label_expr = ctx.args[ctx.callee_arg_names.index('app_label')][0]
    app_label = get_string_value_from_expr(app_label_expr)
    if app_label is None:
        return ctx.default_return_type

    if 'model_name' not in ctx.callee_arg_names:
        return ctx.default_return_type

    model_name_expr_tuple = ctx.args[ctx.callee_arg_names.index('model_name')]
    if not model_name_expr_tuple:
        return ctx.default_return_type

    model_name = get_string_value_from_expr(model_name_expr_tuple[0])
    if model_name is None:
        return ctx.default_return_type

    api = cast(TypeChecker, ctx.api)
    model_fullname = helpers.get_model_fullname(app_label,
                                                model_name,
                                                all_modules=api.modules)

    if model_fullname is None:
        return ctx.default_return_type
    model_info = helpers.lookup_fully_qualified_generic(
        model_fullname, all_modules=api.modules)
    if model_info is None or not isinstance(model_info, TypeInfo):
        return ctx.default_return_type
    return TypeType(Instance(model_info, []))
Esempio n. 2
0
def return_user_model_hook(ctx: FunctionContext) -> Type:
    api = cast(TypeChecker, ctx.api)
    setting_expr = helpers.get_setting_expr(api, 'AUTH_USER_MODEL')
    if setting_expr is None:
        return ctx.default_return_type

    model_path = get_string_value_from_expr(setting_expr)
    if model_path is None:
        return ctx.default_return_type

    app_label, _, model_class_name = model_path.rpartition('.')
    if app_label is None:
        return ctx.default_return_type

    model_fullname = helpers.get_model_fullname(app_label, model_class_name,
                                                all_modules=api.modules)
    if model_fullname is None:
        api.fail(f'"{app_label}.{model_class_name}" model class is not imported so far. Try to import it '
                 f'(under if TYPE_CHECKING) at the beginning of the current file',
                 context=ctx.context)
        return ctx.default_return_type

    model_info = helpers.lookup_fully_qualified_generic(model_fullname,
                                                        all_modules=api.modules)
    if model_info is None or not isinstance(model_info, TypeInfo):
        return ctx.default_return_type
    return TypeType(Instance(model_info, []))
Esempio n. 3
0
def return_user_model_hook(ctx: FunctionContext,
                           settings_modules: List[str]) -> Type:
    from mypy.checker import TypeChecker

    api = cast(TypeChecker, ctx.api)

    setting_sym = get_setting_sym('AUTH_USER_MODEL', api, settings_modules)
    if setting_sym is None:
        return ctx.default_return_type

    setting_module_name, _, _ = setting_sym.fullname.rpartition('.')
    setting_module = api.modules[setting_module_name]

    model_path = None
    for name_expr, rvalue_expr in helpers.iter_over_assignments(
            setting_module):
        if isinstance(name_expr, NameExpr) and isinstance(
                rvalue_expr, StrExpr):
            if name_expr.name == 'AUTH_USER_MODEL':
                model_path = rvalue_expr.value
                break

    if not model_path:
        return ctx.default_return_type

    app_label, _, model_class_name = model_path.rpartition('.')
    if app_label is None:
        return ctx.default_return_type

    model_fullname = helpers.get_model_fullname(app_label,
                                                model_class_name,
                                                all_modules=api.modules)
    if model_fullname is None:
        api.fail(
            f'"{app_label}.{model_class_name}" model class is not imported so far. Try to import it '
            f'(under if TYPE_CHECKING) at the beginning of the current file',
            context=ctx.context)
        return ctx.default_return_type

    model_info = helpers.lookup_fully_qualified_generic(
        model_fullname, all_modules=api.modules)
    if model_info is None or not isinstance(model_info, TypeInfo):
        return ctx.default_return_type
    return TypeType(Instance(model_info, []))
Esempio n. 4
0
def extract_referred_to_type(ctx: FunctionContext) -> Optional[Instance]:
    api = cast(TypeChecker, ctx.api)
    if 'to' not in ctx.callee_arg_names:
        api.msg.fail(
            f'to= parameter must be set for {ctx.context.callee.fullname}',
            context=ctx.context)
        return None

    arg_type = ctx.arg_types[ctx.callee_arg_names.index('to')][0]
    if not isinstance(arg_type, CallableType):
        to_arg_expr = ctx.args[ctx.callee_arg_names.index('to')][0]
        if not isinstance(to_arg_expr, StrExpr):
            # not string, not supported
            return None
        try:
            model_fullname = helpers.get_model_fullname_from_string(
                to_arg_expr.value, all_modules=api.modules)
        except helpers.SelfReference:
            model_fullname = api.tscope.classes[-1].fullname()

        except helpers.SameFileModel as exc:
            model_fullname = api.tscope.classes[
                -1].module_name + '.' + exc.model_cls_name

        if model_fullname is None:
            return None
        model_info = helpers.lookup_fully_qualified_generic(
            model_fullname, all_modules=api.modules)
        if model_info is None or not isinstance(model_info, TypeInfo):
            return None
        return Instance(model_info, [])

    referred_to_type = arg_type.ret_type
    if not isinstance(referred_to_type, Instance):
        return None
    if not referred_to_type.type.has_base(helpers.MODEL_CLASS_FULLNAME):
        ctx.api.msg.fail(
            f'to= parameter value must be '
            f'a subclass of {helpers.MODEL_CLASS_FULLNAME}',
            context=ctx.context)
        return None

    return referred_to_type