def visit_unbound_type(self, t: UnboundType) -> Type: sym = self.lookup(t.name, t) if sym is not None: if sym.kind == TVAR: if len(t.args) > 0: self.fail( 'Type variable "{}" used with arguments'.format( t.name), t) if t.repr: rep = TypeVarRepr(t.repr.components[0]) else: rep = None values = cast(TypeVarExpr, sym.node).values return TypeVar(t.name, sym.tvar_id, values, self.builtin_type('builtins.object'), t.line, rep) elif sym.node.fullname() == 'builtins.None': return Void() elif sym.node.fullname() == 'typing.Any': return AnyType() elif sym.node.fullname() == 'typing.Tuple': return TupleType(self.anal_array(t.args), self.builtin_type('builtins.tuple')) elif sym.node.fullname() == 'typing.Union': return UnionType(self.anal_array(t.args)) elif sym.node.fullname() == 'typing.Function': return self.analyze_function_type(t) elif not isinstance(sym.node, TypeInfo): name = sym.fullname if name is None: name = sym.node.name() if sym.node in self.stored_vars: return self.stored_vars[sym.node] self.fail('Invalid type "{}"'.format(name), t) return t info = cast(TypeInfo, sym.node) if len(t.args) > 0 and info.fullname() == 'builtins.tuple': return TupleType(self.anal_array(t.args), Instance(info, [], t.line), t.line, t.repr) else: # Analyze arguments and construct Instance type. The # number of type arguments and their values are # checked only later, since we do not always know the # valid count at this point. Thus we may construct an # Instance with an invalid number of type arguments. instance = Instance(info, self.anal_array(t.args), t.line, t.repr) if info.tuple_type is None: return instance else: # The class has a Tuple[...] base class so it will be # represented as a tuple type. return TupleType(self.anal_array(info.tuple_type.items), fallback=instance, line=t.line) else: return t
def __init__(self): # Type variables self.t = TypeVar('T', 1) # T`1 (type variable) self.tf = TypeVar('T', -1) # T`-1 (type variable) self.tf2 = TypeVar('T', -2) # T`-2 (type variable) self.s = TypeVar('S', 2) # S`2 (type variable) self.s1 = TypeVar('S', 1) # S`1 (type variable) self.sf = TypeVar('S', -2) # S`-2 (type variable) self.sf1 = TypeVar('S', -1) # S`-1 (type variable) # Simple types self.anyt = AnyType() self.void = Void() self.err = ErrorType() self.nonet = NoneTyp() # Abstract class TypeInfos # class F self.fi = make_type_info('F', is_abstract=True) # class F2 self.f2i = make_type_info('F2', is_abstract=True) # class F3(F) self.f3i = make_type_info('F3', is_abstract=True, mro=[self.fi]) # Class TypeInfos self.oi = make_type_info('builtins.object') # class object self.std_tuplei = make_type_info('builtins.tuple') # class tuple self.type_typei = make_type_info('builtins.type') # class type self.std_functioni = make_type_info('std::Function') # Function TODO self.ai = make_type_info('A', mro=[self.oi]) # class A self.bi = make_type_info('B', mro=[self.ai]) # class B(A) self.ci = make_type_info('C', mro=[self.ai]) # class C(A) self.di = make_type_info('D', mro=[self.oi]) # class D # class E(F) self.ei = make_type_info('E', mro=[self.fi, self.oi]) # class E2(F2, F) self.e2i = make_type_info('E2', mro=[self.f2i, self.fi, self.oi]) # class E3(F, F2) self.e3i = make_type_info('E3', mro=[self.fi, self.f2i, self.oi]) # Generic class TypeInfos # G[T] self.gi = make_type_info('G', mro=[self.oi], typevars=['T']) # G2[T] self.g2i = make_type_info('G2', mro=[self.oi], typevars=['T']) # H[S, T] self.hi = make_type_info('H', mro=[self.oi], typevars=['S', 'T']) # GS[T, S] <: G[S] self.gsi = make_type_info('GS', mro=[self.gi, self.oi], typevars=['T', 'S'], bases=[Instance(self.gi, [self.s])]) # GS2[S] <: G[S] self.gs2i = make_type_info('GS2', mro=[self.gi, self.oi], typevars=['S'], bases=[Instance(self.gi, [self.s1])]) # list[T] self.std_listi = make_type_info('builtins.list', mro=[self.oi], typevars=['T']) # Instance types self.o = Instance(self.oi, []) # object self.std_tuple = Instance(self.std_tuplei, []) # tuple self.type_type = Instance(self.type_typei, []) # type self.std_function = Instance(self.std_functioni, []) # function TODO self.a = Instance(self.ai, []) # A self.b = Instance(self.bi, []) # B self.c = Instance(self.ci, []) # C self.d = Instance(self.di, []) # D self.e = Instance(self.ei, []) # E self.e2 = Instance(self.e2i, []) # E2 self.e3 = Instance(self.e3i, []) # E3 self.f = Instance(self.fi, []) # F self.f2 = Instance(self.f2i, []) # F2 self.f3 = Instance(self.f3i, []) # F3 # Generic instance types self.ga = Instance(self.gi, [self.a]) # G[A] self.gb = Instance(self.gi, [self.b]) # G[B] self.go = Instance(self.gi, [self.o]) # G[object] self.gt = Instance(self.gi, [self.t]) # G[T`1] self.gtf = Instance(self.gi, [self.tf]) # G[T`-1] self.gtf2 = Instance(self.gi, [self.tf2]) # G[T`-2] self.gs = Instance(self.gi, [self.s]) # G[S] self.gdyn = Instance(self.gi, [self.anyt]) # G[Any] self.g2a = Instance(self.g2i, [self.a]) # G2[A] self.gsab = Instance(self.gsi, [self.a, self.b]) # GS[A, B] self.gsba = Instance(self.gsi, [self.b, self.a]) # GS[B, A] self.gs2a = Instance(self.gs2i, [self.a]) # GS2[A] self.hab = Instance(self.hi, [self.a, self.b]) # H[A, B] self.haa = Instance(self.hi, [self.a, self.a]) # H[A, A] self.hbb = Instance(self.hi, [self.b, self.b]) # H[B, B] self.hts = Instance(self.hi, [self.t, self.s]) # H[T, S] self.lsta = Instance(self.std_listi, [self.a]) # List[A] self.lstb = Instance(self.std_listi, [self.b]) # List[B] # Basic types self.basic = BasicTypes(self.o, self.type_type, self.std_tuple, self.std_function)
def visit_type_var(self, t: TypeVar) -> Type: if t.id > 0: return TypeVar(t.name, t.id, OBJECT_VAR, t.line, t.repr) else: return t
def visit_type_var(self, t: TypeVar) -> Type: if t.id > 0: return TypeVar(t.name, t.id, t.values, BOUND_VAR, t.line, t.repr) else: return t
def visit_type_var(self, t: TypeVar) -> Type: if t.id < 0: return t else: return TypeVar(t.name, -t.id - self.num_func_tvars, t.values)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from typing import Callable, Optional, Type as TypingType, Union from mypy.errorcodes import ErrorCode from mypy.nodes import FuncBase, SymbolNode from mypy.options import Options from mypy.plugin import AnalyzeTypeContext, Plugin from mypy.semanal import set_callable_name # type: ignore from mypy.types import Type, TypeVar T = TypeVar("T") VALIDATOR_TYPE = "strongtyping.strong_typing_utils.Validator" # type: Final ERROR_UNEXPECTED = ErrorCode("strongtyping-unexpected", "Unexpected behavior", "strongtyping") def plugin(version: str) -> "TypingType[Plugin]": """ `version` is the mypy version string We might want to use this to print a warning if the mypy version being used is newer, or especially older, than we expect (or need). """ return StrongtypingPlugin class StrongtypingPlugin(Plugin): def __init__(self, options: Options) -> None: super().__init__(options)