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)
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)
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)
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)
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))
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)
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
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
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
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