@@ -2808,6 +2808,7 @@ def get_declared_metaclass(
28082808 and not sym .node .alias_tvars
28092809 ):
28102810 target = get_proper_type (sym .node .target )
2811+ self .add_type_alias_deps ({(sym .node .module , sym .node .fullname )})
28112812 if isinstance (target , Instance ):
28122813 metaclass_info = target .type
28132814
@@ -3886,16 +3887,15 @@ def analyze_alias(
38863887 declared_type_vars : TypeVarLikeList | None = None ,
38873888 all_declared_type_params_names : list [str ] | None = None ,
38883889 python_3_12_type_alias : bool = False ,
3889- ) -> tuple [Type | None , list [TypeVarLikeType ], set [str ], list [ str ], bool ]:
3890+ ) -> tuple [Type | None , list [TypeVarLikeType ], set [tuple [ str , str ] ], bool ]:
38903891 """Check if 'rvalue' is a valid type allowed for aliasing (e.g. not a type variable).
38913892
3892- If yes, return the corresponding type, a list of
3893- qualified type variable names for generic aliases, a set of names the alias depends on,
3894- and a list of type variables if the alias is generic.
3895- A schematic example for the dependencies:
3893+ If yes, return the corresponding type, a list of type variables for generic aliases,
3894+ a set of names the alias depends on, and True if the original type has empty tuple index.
3895+ An example for the dependencies:
38963896 A = int
38973897 B = str
3898- analyze_alias(Dict [A, B])[2] == {'__main__ .A', '__main__ .B'}
3898+ analyze_alias(dict [A, B])[2] == {('mod', 'mod .A'), ('mod', 'mod .B') }
38993899 """
39003900 dynamic = bool (self .function_stack and self .function_stack [- 1 ].is_dynamic ())
39013901 global_scope = not self .type and not self .function_stack
@@ -3907,10 +3907,9 @@ def analyze_alias(
39073907 self .fail (
39083908 "Invalid type alias: expression is not a valid type" , rvalue , code = codes .VALID_TYPE
39093909 )
3910- return None , [], set (), [], False
3910+ return None , [], set (), False
39113911
39123912 found_type_vars = self .find_type_var_likes (typ )
3913- tvar_defs : list [TypeVarLikeType ] = []
39143913 namespace = self .qualified_name (name )
39153914 alias_type_vars = found_type_vars if declared_type_vars is None else declared_type_vars
39163915 with self .tvar_scope_frame (self .tvar_scope .class_frame (namespace )):
@@ -3946,9 +3945,8 @@ def analyze_alias(
39463945 variadic = True
39473946 new_tvar_defs .append (td )
39483947
3949- qualified_tvars = [node .fullname for _name , node in alias_type_vars ]
39503948 empty_tuple_index = typ .empty_tuple_index if isinstance (typ , UnboundType ) else False
3951- return analyzed , new_tvar_defs , depends_on , qualified_tvars , empty_tuple_index
3949+ return analyzed , new_tvar_defs , depends_on , empty_tuple_index
39523950
39533951 def is_pep_613 (self , s : AssignmentStmt ) -> bool :
39543952 if s .unanalyzed_type is not None and isinstance (s .unanalyzed_type , UnboundType ):
@@ -4042,12 +4040,11 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool:
40424040 if self .is_none_alias (rvalue ):
40434041 res = NoneType ()
40444042 alias_tvars : list [TypeVarLikeType ] = []
4045- depends_on : set [str ] = set ()
4046- qualified_tvars : list [str ] = []
4043+ depends_on : set [tuple [str , str ]] = set ()
40474044 empty_tuple_index = False
40484045 else :
40494046 tag = self .track_incomplete_refs ()
4050- res , alias_tvars , depends_on , qualified_tvars , empty_tuple_index = self .analyze_alias (
4047+ res , alias_tvars , depends_on , empty_tuple_index = self .analyze_alias (
40514048 lvalue .name ,
40524049 rvalue ,
40534050 allow_placeholder = True ,
@@ -4071,12 +4068,6 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool:
40714068 self .mark_incomplete (lvalue .name , rvalue , becomes_typeinfo = True )
40724069 return True
40734070 self .add_type_alias_deps (depends_on )
4074- # In addition to the aliases used, we add deps on unbound
4075- # type variables, since they are erased from target type.
4076- self .add_type_alias_deps (qualified_tvars )
4077- # The above are only direct deps on other aliases.
4078- # For subscripted aliases, type deps from expansion are added in deps.py
4079- # (because the type is stored).
40804071 check_for_explicit_any (res , self .options , self .is_typeshed_stub_file , self .msg , context = s )
40814072 # When this type alias gets "inlined", the Any is not explicit anymore,
40824073 # so we need to replace it with non-explicit Anys.
@@ -5579,7 +5570,7 @@ def visit_type_alias_stmt(self, s: TypeAliasStmt) -> None:
55795570 return
55805571
55815572 tag = self .track_incomplete_refs ()
5582- res , alias_tvars , depends_on , qualified_tvars , empty_tuple_index = self .analyze_alias (
5573+ res , alias_tvars , depends_on , empty_tuple_index = self .analyze_alias (
55835574 s .name .name ,
55845575 s .value .expr (),
55855576 allow_placeholder = True ,
@@ -5608,12 +5599,6 @@ def visit_type_alias_stmt(self, s: TypeAliasStmt) -> None:
56085599 return
56095600
56105601 self .add_type_alias_deps (depends_on )
5611- # In addition to the aliases used, we add deps on unbound
5612- # type variables, since they are erased from target type.
5613- self .add_type_alias_deps (qualified_tvars )
5614- # The above are only direct deps on other aliases.
5615- # For subscripted aliases, type deps from expansion are added in deps.py
5616- # (because the type is stored).
56175602 check_for_explicit_any (
56185603 res , self .options , self .is_typeshed_stub_file , self .msg , context = s
56195604 )
@@ -7541,20 +7526,21 @@ def add_plugin_dependency(self, trigger: str, target: str | None = None) -> None
75417526 self .cur_mod_node .plugin_deps .setdefault (trigger , set ()).add (target )
75427527
75437528 def add_type_alias_deps (
7544- self , aliases_used : Collection [str ], target : str | None = None
7529+ self , aliases_used : Collection [tuple [ str , str ] ], target : str | None = None
75457530 ) -> None :
75467531 """Add full names of type aliases on which the current node depends.
75477532
75487533 This is used by fine-grained incremental mode to re-check the corresponding nodes.
7549- If `target` is None, then the target node used will be the current scope.
7534+ If `target` is None, then the target node used will be the current scope. For
7535+ coarse-grained mode, add just the module names where aliases are defined.
75507536 """
75517537 if not aliases_used :
7552- # A basic optimization to avoid adding targets with no dependencies to
7553- # the `alias_deps` dict.
75547538 return
75557539 if target is None :
75567540 target = self .scope .current_target ()
7557- self .cur_mod_node .alias_deps [target ].update (aliases_used )
7541+ for mod , fn in aliases_used :
7542+ self .cur_mod_node .alias_deps [target ].add (fn )
7543+ self .cur_mod_node .mod_alias_deps .add (mod )
75587544
75597545 def is_mangled_global (self , name : str ) -> bool :
75607546 # A global is mangled if there exists at least one renamed variant.
0 commit comments