@@ -618,7 +618,7 @@ def accept_loop(
618618 if on_enter_body is not None :
619619 on_enter_body ()
620620
621- with IterationErrorWatcher (self .msg .errors , iter_errors ) as watcher :
621+ with IterationErrorWatcher (self .msg .errors , iter_errors ):
622622 self .accept (body )
623623
624624 partials_new = sum (len (pts .map ) for pts in self .partial_types )
@@ -641,10 +641,7 @@ def accept_loop(
641641 if iter == 20 :
642642 raise RuntimeError ("Too many iterations when checking a loop" )
643643
644- for error_info in watcher .yield_error_infos ():
645- self .msg .fail (* error_info [:2 ], code = error_info [2 ])
646- for note_info in watcher .yield_note_infos (self .options ):
647- self .note (* note_info )
644+ self .msg .iteration_dependent_errors (iter_errors )
648645
649646 # If exit_condition is set, assume it must be False on exit from the loop:
650647 if exit_condition :
@@ -3041,7 +3038,7 @@ def is_noop_for_reachability(self, s: Statement) -> bool:
30413038 if isinstance (s .expr , EllipsisExpr ):
30423039 return True
30433040 elif isinstance (s .expr , CallExpr ):
3044- with self .expr_checker .msg .filter_errors ():
3041+ with self .expr_checker .msg .filter_errors (filter_revealed_type = True ):
30453042 typ = get_proper_type (
30463043 self .expr_checker .accept (
30473044 s .expr , allow_none_return = True , always_allow_any = True
@@ -3141,7 +3138,7 @@ def check_assignment(
31413138 else :
31423139 self .check_getattr_method (signature , lvalue , name )
31433140
3144- if name == "__slots__" :
3141+ if name == "__slots__" and self . scope . active_class () is not None :
31453142 typ = lvalue_type or self .expr_checker .accept (rvalue )
31463143 self .check_slots_definition (typ , lvalue )
31473144 if name == "__match_args__" and inferred is not None :
@@ -3320,6 +3317,12 @@ def get_variable_type_context(self, inferred: Var, rvalue: Expression) -> Type |
33203317 type_contexts .append (base_type )
33213318 # Use most derived supertype as type context if available.
33223319 if not type_contexts :
3320+ if inferred .name == "__slots__" and self .scope .active_class () is not None :
3321+ str_type = self .named_type ("builtins.str" )
3322+ return self .named_generic_type ("typing.Iterable" , [str_type ])
3323+ if inferred .name == "__all__" and self .scope .is_top_level ():
3324+ str_type = self .named_type ("builtins.str" )
3325+ return self .named_generic_type ("typing.Sequence" , [str_type ])
33233326 return None
33243327 candidate = type_contexts [0 ]
33253328 for other in type_contexts :
@@ -4972,7 +4975,7 @@ def visit_try_stmt(self, s: TryStmt) -> None:
49724975 if s .finally_body :
49734976 # First we check finally_body is type safe on all abnormal exit paths
49744977 iter_errors = IterationDependentErrors ()
4975- with IterationErrorWatcher (self .msg .errors , iter_errors ) as watcher :
4978+ with IterationErrorWatcher (self .msg .errors , iter_errors ):
49764979 self .accept (s .finally_body )
49774980
49784981 if s .finally_body :
@@ -4989,13 +4992,9 @@ def visit_try_stmt(self, s: TryStmt) -> None:
49894992 # that follows the try statement.)
49904993 assert iter_errors is not None
49914994 if not self .binder .is_unreachable ():
4992- with IterationErrorWatcher (self .msg .errors , iter_errors ) as watcher :
4995+ with IterationErrorWatcher (self .msg .errors , iter_errors ):
49934996 self .accept (s .finally_body )
4994-
4995- for error_info in watcher .yield_error_infos ():
4996- self .msg .fail (* error_info [:2 ], code = error_info [2 ])
4997- for note_info in watcher .yield_note_infos (self .options ):
4998- self .msg .note (* note_info )
4997+ self .msg .iteration_dependent_errors (iter_errors )
49994998
50004999 def visit_try_without_finally (self , s : TryStmt , try_frame : bool ) -> None :
50015000 """Type check a try statement, ignoring the finally block.
@@ -7283,7 +7282,7 @@ def named_type(self, name: str) -> Instance:
72837282 if isinstance (node , TypeAlias ):
72847283 assert isinstance (node .target , Instance ) # type: ignore[misc]
72857284 node = node .target .type
7286- assert isinstance (node , TypeInfo )
7285+ assert isinstance (node , TypeInfo ), node
72877286 any_type = AnyType (TypeOfAny .from_omitted_generics )
72887287 return Instance (node , [any_type ] * len (node .defn .type_vars ))
72897288
@@ -7302,7 +7301,7 @@ def lookup_typeinfo(self, fullname: str) -> TypeInfo:
73027301 # Assume that the name refers to a class.
73037302 sym = self .lookup_qualified (fullname )
73047303 node = sym .node
7305- assert isinstance (node , TypeInfo )
7304+ assert isinstance (node , TypeInfo ), node
73067305 return node
73077306
73087307 def type_type (self ) -> Instance :
@@ -7893,6 +7892,9 @@ def has_valid_attribute(self, typ: Type, name: str) -> bool:
78937892 def get_expression_type (self , node : Expression , type_context : Type | None = None ) -> Type :
78947893 return self .expr_checker .accept (node , type_context = type_context )
78957894
7895+ def is_defined_in_stub (self , typ : Instance , / ) -> bool :
7896+ return self .modules [typ .type .module_name ].is_stub
7897+
78967898 def check_deprecated (self , node : Node | None , context : Context ) -> None :
78977899 """Warn if deprecated and not directly imported with a `from` statement."""
78987900 if isinstance (node , Decorator ):
0 commit comments