6262 ParamSpecType ,
6363 PartialType ,
6464 PlaceholderType ,
65+ ProperType ,
6566 RawExpressionType ,
6667 RequiredType ,
6768 SyntheticTypeVisitor ,
8990 has_type_vars ,
9091)
9192from mypy .types_utils import is_bad_type_type_item
92- from mypy .typetraverser import TypeTraverserVisitor
9393from mypy .typevars import fill_typevars
9494
9595T = TypeVar ("T" )
@@ -425,9 +425,10 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
425425 # The only case where instantiate_type_alias() can return an incorrect instance is
426426 # when it is top-level instance, so no need to recurse.
427427 if (
428- isinstance (res , Instance ) # type: ignore[misc]
429- and not self .defining_alias
430- and not validate_instance (res , self .fail )
428+ isinstance (res , ProperType )
429+ and isinstance (res , Instance )
430+ and not (self .defining_alias and self .nesting_level == 0 )
431+ and not validate_instance (res , self .fail , t .empty_tuple_index )
431432 ):
432433 fix_instance (
433434 res ,
@@ -442,7 +443,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
442443 res = get_proper_type (res )
443444 return res
444445 elif isinstance (node , TypeInfo ):
445- return self .analyze_type_with_type_info (node , t .args , t )
446+ return self .analyze_type_with_type_info (node , t .args , t , t . empty_tuple_index )
446447 elif node .fullname in TYPE_ALIAS_NAMES :
447448 return AnyType (TypeOfAny .special_form )
448449 # Concatenate is an operator, no need for a proper type
@@ -700,7 +701,7 @@ def get_omitted_any(self, typ: Type, fullname: str | None = None) -> AnyType:
700701 return get_omitted_any (disallow_any , self .fail , self .note , typ , self .options , fullname )
701702
702703 def analyze_type_with_type_info (
703- self , info : TypeInfo , args : Sequence [Type ], ctx : Context
704+ self , info : TypeInfo , args : Sequence [Type ], ctx : Context , empty_tuple_index : bool
704705 ) -> Type :
705706 """Bind unbound type when were able to find target TypeInfo.
706707
@@ -735,7 +736,9 @@ def analyze_type_with_type_info(
735736
736737 # Check type argument count.
737738 instance .args = tuple (flatten_nested_tuples (instance .args ))
738- if not self .defining_alias and not validate_instance (instance , self .fail ):
739+ if not (self .defining_alias and self .nesting_level == 0 ) and not validate_instance (
740+ instance , self .fail , empty_tuple_index
741+ ):
739742 fix_instance (
740743 instance ,
741744 self .fail ,
@@ -1203,7 +1206,7 @@ def visit_placeholder_type(self, t: PlaceholderType) -> Type:
12031206 else :
12041207 # TODO: Handle non-TypeInfo
12051208 assert isinstance (n .node , TypeInfo )
1206- return self .analyze_type_with_type_info (n .node , t .args , t )
1209+ return self .analyze_type_with_type_info (n .node , t .args , t , False )
12071210
12081211 def analyze_callable_args_for_paramspec (
12091212 self , callable_args : Type , ret_type : Type , fallback : Instance
@@ -2256,7 +2259,7 @@ def make_optional_type(t: Type) -> Type:
22562259 return UnionType ([t , NoneType ()], t .line , t .column )
22572260
22582261
2259- def validate_instance (t : Instance , fail : MsgCallback ) -> bool :
2262+ def validate_instance (t : Instance , fail : MsgCallback , empty_tuple_index : bool ) -> bool :
22602263 """Check if this is a well-formed instance with respect to argument count/positions."""
22612264 # TODO: combine logic with instantiate_type_alias().
22622265 if any (unknown_unpack (a ) for a in t .args ):
@@ -2279,8 +2282,9 @@ def validate_instance(t: Instance, fail: MsgCallback) -> bool:
22792282 )
22802283 return False
22812284 elif not t .args :
2282- # The Any arguments should be set by the caller.
2283- return False
2285+ if not (empty_tuple_index and len (t .type .type_vars ) == 1 ):
2286+ # The Any arguments should be set by the caller.
2287+ return False
22842288 else :
22852289 # We also need to check if we are not performing a type variable tuple split.
22862290 unpack = find_unpack_in_list (t .args )
@@ -2313,34 +2317,6 @@ def validate_instance(t: Instance, fail: MsgCallback) -> bool:
23132317 return True
23142318
23152319
2316- def fix_instance_types (t : Type , fail : MsgCallback , note : MsgCallback , options : Options ) -> None :
2317- """Recursively fix all instance types (type argument count) in a given type.
2318-
2319- For example 'Union[Dict, List[str, int]]' will be transformed into
2320- 'Union[Dict[Any, Any], List[Any]]' in place.
2321- """
2322- t .accept (InstanceFixer (fail , note , options ))
2323-
2324-
2325- class InstanceFixer (TypeTraverserVisitor ):
2326- def __init__ (self , fail : MsgCallback , note : MsgCallback , options : Options ) -> None :
2327- self .fail = fail
2328- self .note = note
2329- self .options = options
2330-
2331- def visit_instance (self , typ : Instance ) -> None :
2332- super ().visit_instance (typ )
2333- if not validate_instance (typ , self .fail ):
2334- fix_instance (
2335- typ ,
2336- self .fail ,
2337- self .note ,
2338- disallow_any = False ,
2339- options = self .options ,
2340- use_generic_error = True ,
2341- )
2342-
2343-
23442320def find_self_type (typ : Type , lookup : Callable [[str ], SymbolTableNode | None ]) -> bool :
23452321 return typ .accept (HasSelfType (lookup ))
23462322
0 commit comments