Beispiel #1
0
def datafile_class_maker_callback(ctx: ClassDefContext) -> None:
    # Inherit all type definitions from dataclasses
    DataclassTransformer(ctx).transform()

    # Define 'objects' as a class propery
    var = Var("objects", AnyType(TypeOfAny.unannotated))
    var.info = ctx.cls.info
    var.is_property = True
    ctx.cls.info.names[var.name] = SymbolTableNode(MDEF, var)

    # Define 'datafile' as an instance property
    var = Var("datafile", AnyType(TypeOfAny.unannotated))
    var.info = ctx.cls.info
    var.is_property = True
    ctx.cls.info.names[var.name] = SymbolTableNode(MDEF, var)
Beispiel #2
0
 def add_field(var: Var, is_initialized_in_class: bool = False,
               is_property: bool = False) -> None:
     var.info = info
     var.is_initialized_in_class = is_initialized_in_class
     var.is_property = is_property
     var._fullname = '%s.%s' % (info.fullname, var.name)
     info.names[var.name] = SymbolTableNode(MDEF, var)
Beispiel #3
0
def _add_attrs_magic_attribute(
        ctx: 'mypy.plugin.ClassDefContext',
        attrs: 'List[Tuple[str, Optional[Type]]]') -> None:
    any_type = AnyType(TypeOfAny.explicit)
    attributes_types: 'List[Type]' = [
        ctx.api.named_type_or_none('attr.Attribute', [attr_type or any_type])
        or any_type for _, attr_type in attrs
    ]
    fallback_type = ctx.api.named_type('builtins.tuple', [
        ctx.api.named_type_or_none('attr.Attribute', [any_type]) or any_type,
    ])

    ti = ctx.api.basic_new_typeinfo(MAGIC_ATTR_CLS_NAME, fallback_type, 0)
    ti.is_named_tuple = True
    for (name, _), attr_type in zip(attrs, attributes_types):
        var = Var(name, attr_type)
        var.is_property = True
        proper_type = get_proper_type(attr_type)
        if isinstance(proper_type, Instance):
            var.info = proper_type.type
        ti.names[name] = SymbolTableNode(MDEF, var, plugin_generated=True)
    attributes_type = Instance(ti, [])

    # TODO: refactor using `add_attribute_to_class`
    var = Var(name=MAGIC_ATTR_NAME,
              type=TupleType(attributes_types, fallback=attributes_type))
    var.info = ctx.cls.info
    var.is_classvar = True
    var._fullname = f"{ctx.cls.fullname}.{MAGIC_ATTR_CLS_NAME}"
    ctx.cls.info.names[MAGIC_ATTR_NAME] = SymbolTableNode(
        kind=MDEF,
        node=var,
        plugin_generated=True,
        no_serialize=True,
    )
def add_property(cls_node: TypeInfo, ans_cls_node: TypeInfo,
                 prop_node: Expression,
                 api: SemanticAnalyzerPluginInterface) -> None:
    """Add a property."""
    if not isinstance(prop_node, StrExpr):
        api.fail('Keyword must be a string literal',
                 prop_node,
                 code=VALID_TYPE)
        return
    prop_name = prop_node.value

    try:
        ans_type = ans_cls_node[prop_name].type
    except KeyError:
        api.fail(
            f'Attribute `{prop_name}` does not exist in '
            f'{ans_cls_node.name} or its parents',
            prop_node,
            code=ATTR_DEFINED)
        return

    prop_type = get_transformed_type(cls_node, ans_type, prop_node, api)
    if prop_type is None:
        return

    if not has_default(cls_node, prop_node, api) and prop_type is not None:
        prop_type = make_optional(prop_type)

    new_prop = Var(prop_name, api.anal_type(prop_type))
    new_prop.info = cls_node
    new_prop.is_initialized_in_class = True
    new_prop.is_property = True

    cls_node.names[prop_name] = SymbolTableNode(MDEF, new_prop)
Beispiel #5
0
 def add_field(var: Var, is_initialized_in_class: bool = False,
               is_property: bool = False) -> None:
     var.info = info
     var.is_initialized_in_class = is_initialized_in_class
     var.is_property = is_property
     var._fullname = '%s.%s' % (info.fullname(), var.name())
     info.names[var.name()] = SymbolTableNode(MDEF, var)
Beispiel #6
0
def query_callback(ctx: DynamicClassDefContext) -> TypeInfo:
    # todo be defensive--ctx.type is Schema[Literal[fname]]
    #fname = ctx.arg_types[0].value
    query = ctx.call.args[1].value
    defn = ClassDef(
        ctx.name,
        defs=Block([
            mpn.AssignmentStmt(
                lvalues=mpn.NameExpr,
                rvalue=None,
                type=ctx.api.lookup_fully_qualified_or_none('builtins.str'),
                new_syntax=True)
        ]))
    defn.fullname = ctx.api.qualified_name(ctx.name)
    names = SymbolTable()
    var = Var('me', ctx.api.builtin_type('builtins.str'))
    var.info = var.type.type
    var.is_property = True
    names['me'] = SymbolTableNode(MDEF, var, plugin_generated=True)
    info = TypeInfo(names=names, defn=defn, module_name=ctx.api.cur_mod_id)
    obj = ctx.api.builtin_type('builtins.object')
    info.mro = [info, obj.type]
    info.bases = [obj]
    print(ctx.name, info)
    ctx.api.add_symbol_table_node(ctx.name, SymbolTableNode(GDEF, info))
Beispiel #7
0
 def add_field_to_new_typeinfo(var: Var,
                               is_initialized_in_class: bool = False,
                               is_property: bool = False) -> None:
     var.info = new_typeinfo
     var.is_initialized_in_class = is_initialized_in_class
     var.is_property = is_property
     var._fullname = new_typeinfo.fullname() + '.' + var.name()
     new_typeinfo.names[var.name()] = SymbolTableNode(MDEF, var)
Beispiel #8
0
 def build_enum_call_typeinfo(self, name: str, items: List[str], fullname: str) -> TypeInfo:
     base = self.api.named_type_or_none(fullname)
     assert base is not None
     info = self.api.basic_new_typeinfo(name, base)
     info.metaclass_type = info.calculate_metaclass_type()
     info.is_enum = True
     for item in items:
         var = Var(item)
         var.info = info
         var.is_property = True
         var._fullname = '{}.{}'.format(self.api.qualified_name(name), item)
         info.names[item] = SymbolTableNode(MDEF, var)
     return info
Beispiel #9
0
 def build_enum_call_typeinfo(self, name: str, items: List[str], fullname: str) -> TypeInfo:
     base = self.api.named_type_or_none(fullname)
     assert base is not None
     info = self.api.basic_new_typeinfo(name, base)
     info.metaclass_type = info.calculate_metaclass_type()
     info.is_enum = True
     for item in items:
         var = Var(item)
         var.info = info
         var.is_property = True
         var._fullname = '{}.{}'.format(self.api.qualified_name(name), item)
         info.names[item] = SymbolTableNode(MDEF, var)
     return info
Beispiel #10
0
def _make_frozen(ctx: 'mypy.plugin.ClassDefContext', attributes: List[Attribute]) -> None:
    """Turn all the attributes into properties to simulate frozen classes."""
    for attribute in attributes:
        if attribute.name in ctx.cls.info.names:
            # This variable belongs to this class so we can modify it.
            node = ctx.cls.info.names[attribute.name].node
            assert isinstance(node, Var)
            node.is_property = True
        else:
            # This variable belongs to a super class so create new Var so we
            # can modify it.
            var = Var(attribute.name, ctx.cls.info[attribute.name].type)
            var.info = ctx.cls.info
            var._fullname = '%s.%s' % (ctx.cls.info.fullname, var.name)
            ctx.cls.info.names[var.name] = SymbolTableNode(MDEF, var)
            var.is_property = True
Beispiel #11
0
 def visit_var(self, node: Var) -> Var:
     # Note that a Var must be transformed to a Var.
     if node in self.var_map:
         return self.var_map[node]
     new = Var(node.name(), self.optional_type(node.type))
     new.line = node.line
     new._fullname = node._fullname
     new.info = node.info
     new.is_self = node.is_self
     new.is_ready = node.is_ready
     new.is_initialized_in_class = node.is_initialized_in_class
     new.is_staticmethod = node.is_staticmethod
     new.is_property = node.is_property
     new.set_line(node.line)
     self.var_map[node] = new
     return new
Beispiel #12
0
def _make_frozen(ctx: 'mypy.plugin.ClassDefContext', attributes: List[Attribute]) -> None:
    """Turn all the attributes into properties to simulate frozen classes."""
    for attribute in attributes:
        if attribute.name in ctx.cls.info.names:
            # This variable belongs to this class so we can modify it.
            node = ctx.cls.info.names[attribute.name].node
            assert isinstance(node, Var)
            node.is_property = True
        else:
            # This variable belongs to a super class so create new Var so we
            # can modify it.
            var = Var(attribute.name, ctx.cls.info[attribute.name].type)
            var.info = ctx.cls.info
            var._fullname = '%s.%s' % (ctx.cls.info.fullname(), var.name())
            ctx.cls.info.names[var.name()] = SymbolTableNode(MDEF, var)
            var.is_property = True
Beispiel #13
0
 def visit_var(self, node: Var) -> Var:
     # Note that a Var must be transformed to a Var.
     if node in self.var_map:
         return self.var_map[node]
     new = Var(node.name(), self.optional_type(node.type))
     new.line = node.line
     new._fullname = node._fullname
     new.info = node.info
     new.is_self = node.is_self
     new.is_ready = node.is_ready
     new.is_initialized_in_class = node.is_initialized_in_class
     new.is_staticmethod = node.is_staticmethod
     new.is_property = node.is_property
     new.set_line(node.line)
     self.var_map[node] = new
     return new