@@ -395,6 +395,8 @@ class TypeChecker(NodeVisitor[None], TypeCheckerSharedApi):
395395
396396 # A helper state to produce unique temporary names on demand.
397397 _unique_id : int
398+ # Fake concrete type used when checking variance
399+ _variance_dummy_type : Instance | None
398400
399401 def __init__ (
400402 self ,
@@ -469,6 +471,7 @@ def __init__(
469471
470472 self .pattern_checker = PatternChecker (self , self .msg , self .plugin , options )
471473 self ._unique_id = 0
474+ self ._variance_dummy_type = None
472475
473476 @property
474477 def expr_checker (self ) -> mypy .checkexpr .ExpressionChecker :
@@ -2918,17 +2921,19 @@ def check_protocol_variance(self, defn: ClassDef) -> None:
29182921 info = defn .info
29192922 object_type = Instance (info .mro [- 1 ], [])
29202923 tvars = info .defn .type_vars
2924+ if self ._variance_dummy_type is None :
2925+ _ , dummy_info = self .make_fake_typeinfo ("<dummy>" , "Dummy" , "Dummy" , [])
2926+ self ._variance_dummy_type = Instance (dummy_info , [])
2927+ dummy = self ._variance_dummy_type
29212928 for i , tvar in enumerate (tvars ):
29222929 if not isinstance (tvar , TypeVarType ):
29232930 # Variance of TypeVarTuple and ParamSpec is underspecified by PEPs.
29242931 continue
29252932 up_args : list [Type ] = [
2926- object_type if i == j else AnyType (TypeOfAny .special_form )
2927- for j , _ in enumerate (tvars )
2933+ object_type if i == j else dummy .copy_modified () for j , _ in enumerate (tvars )
29282934 ]
29292935 down_args : list [Type ] = [
2930- UninhabitedType () if i == j else AnyType (TypeOfAny .special_form )
2931- for j , _ in enumerate (tvars )
2936+ UninhabitedType () if i == j else dummy .copy_modified () for j , _ in enumerate (tvars )
29322937 ]
29332938 up , down = Instance (info , up_args ), Instance (info , down_args )
29342939 # TODO: add advanced variance checks for recursive protocols
0 commit comments