Beispiel #1
0
    def get_meta_attribute(self, name: str) -> Optional[Expression]:
        meta_node = self.get_nested_meta_node()
        if meta_node is None:
            return None

        for lvalue, rvalue in iter_over_assignments(meta_node.defn):
            if isinstance(lvalue, NameExpr) and lvalue.name == name:
                return rvalue
Beispiel #2
0
def record_field_properties_into_outer_model_class(
        ctx: FunctionContext) -> None:
    api = cast(TypeChecker, ctx.api)
    outer_model = api.scope.active_class()
    if outer_model is None or not outer_model.has_base(
            helpers.MODEL_CLASS_FULLNAME):
        # outside models.Model class, undetermined
        return

    field_name = None
    for name_expr, stmt in helpers.iter_over_assignments(outer_model.defn):
        if stmt == ctx.context and isinstance(name_expr, NameExpr):
            field_name = name_expr.name
            break
    if field_name is None:
        return

    fields_metadata = outer_model.metadata.setdefault('django', {}).setdefault(
        'fields', {})

    # primary key
    is_primary_key = False
    primary_key_arg = helpers.get_argument_by_name(ctx, 'primary_key')
    if primary_key_arg:
        is_primary_key = helpers.parse_bool(primary_key_arg)
    fields_metadata[field_name] = {'primary_key': is_primary_key}

    # choices
    choices_arg = helpers.get_argument_by_name(ctx, 'choices')
    if choices_arg and isinstance(choices_arg, (TupleExpr, ListExpr)):
        # iterable of 2 element tuples of two kinds
        _, analyzed_choices = api.analyze_iterable_item_type(choices_arg)
        if isinstance(analyzed_choices, TupleType):
            first_element_type = analyzed_choices.items[0]
            if isinstance(first_element_type, Instance):
                fields_metadata[field_name][
                    'choices'] = first_element_type.type.fullname()

    # nullability
    null_arg = helpers.get_argument_by_name(ctx, 'null')
    is_nullable = False
    if null_arg:
        is_nullable = helpers.parse_bool(null_arg)
    fields_metadata[field_name]['null'] = is_nullable

    # is_blankable
    blank_arg = helpers.get_argument_by_name(ctx, 'blank')
    is_blankable = False
    if blank_arg:
        is_blankable = helpers.parse_bool(blank_arg)
    fields_metadata[field_name]['blank'] = is_blankable

    # default
    default_arg = helpers.get_argument_by_name(ctx, 'default')
    if default_arg and not helpers.is_none_expr(default_arg):
        fields_metadata[field_name]['default_specified'] = True
Beispiel #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, []))
Beispiel #4
0
def iter_call_assignments(
        klass: ClassDef) -> Iterator[Tuple[Lvalue, CallExpr]]:
    for lvalue, rvalue in helpers.iter_over_assignments(klass):
        if isinstance(rvalue, CallExpr):
            yield lvalue, rvalue