@@ -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 :
@@ -3044,7 +3041,7 @@ def is_noop_for_reachability(self, s: Statement) -> bool:
30443041 if isinstance (s .expr , EllipsisExpr ):
30453042 return True
30463043 elif isinstance (s .expr , CallExpr ):
3047- with self .expr_checker .msg .filter_errors ():
3044+ with self .expr_checker .msg .filter_errors (filter_revealed_type = True ):
30483045 typ = get_proper_type (
30493046 self .expr_checker .accept (
30503047 s .expr , allow_none_return = True , always_allow_any = True
@@ -3144,7 +3141,7 @@ def check_assignment(
31443141 else :
31453142 self .check_getattr_method (signature , lvalue , name )
31463143
3147- if name == "__slots__" :
3144+ if name == "__slots__" and self . scope . active_class () is not None :
31483145 typ = lvalue_type or self .expr_checker .accept (rvalue )
31493146 self .check_slots_definition (typ , lvalue )
31503147 if name == "__match_args__" and inferred is not None :
@@ -3323,6 +3320,12 @@ def get_variable_type_context(self, inferred: Var, rvalue: Expression) -> Type |
33233320 type_contexts .append (base_type )
33243321 # Use most derived supertype as type context if available.
33253322 if not type_contexts :
3323+ if inferred .name == "__slots__" and self .scope .active_class () is not None :
3324+ str_type = self .named_type ("builtins.str" )
3325+ return self .named_generic_type ("typing.Iterable" , [str_type ])
3326+ if inferred .name == "__all__" and self .scope .is_top_level ():
3327+ str_type = self .named_type ("builtins.str" )
3328+ return self .named_generic_type ("typing.Sequence" , [str_type ])
33263329 return None
33273330 candidate = type_contexts [0 ]
33283331 for other in type_contexts :
@@ -4984,7 +4987,7 @@ def visit_try_stmt(self, s: TryStmt) -> None:
49844987 if s .finally_body :
49854988 # First we check finally_body is type safe on all abnormal exit paths
49864989 iter_errors = IterationDependentErrors ()
4987- with IterationErrorWatcher (self .msg .errors , iter_errors ) as watcher :
4990+ with IterationErrorWatcher (self .msg .errors , iter_errors ):
49884991 self .accept (s .finally_body )
49894992
49904993 if s .finally_body :
@@ -5001,13 +5004,9 @@ def visit_try_stmt(self, s: TryStmt) -> None:
50015004 # that follows the try statement.)
50025005 assert iter_errors is not None
50035006 if not self .binder .is_unreachable ():
5004- with IterationErrorWatcher (self .msg .errors , iter_errors ) as watcher :
5007+ with IterationErrorWatcher (self .msg .errors , iter_errors ):
50055008 self .accept (s .finally_body )
5006-
5007- for error_info in watcher .yield_error_infos ():
5008- self .msg .fail (* error_info [:2 ], code = error_info [2 ])
5009- for note_info in watcher .yield_note_infos (self .options ):
5010- self .msg .note (* note_info )
5009+ self .msg .iteration_dependent_errors (iter_errors )
50115010
50125011 def visit_try_without_finally (self , s : TryStmt , try_frame : bool ) -> None :
50135012 """Type check a try statement, ignoring the finally block.
@@ -7295,7 +7294,7 @@ def named_type(self, name: str) -> Instance:
72957294 if isinstance (node , TypeAlias ):
72967295 assert isinstance (node .target , Instance ) # type: ignore[misc]
72977296 node = node .target .type
7298- assert isinstance (node , TypeInfo )
7297+ assert isinstance (node , TypeInfo ), node
72997298 any_type = AnyType (TypeOfAny .from_omitted_generics )
73007299 return Instance (node , [any_type ] * len (node .defn .type_vars ))
73017300
@@ -7314,7 +7313,7 @@ def lookup_typeinfo(self, fullname: str) -> TypeInfo:
73147313 # Assume that the name refers to a class.
73157314 sym = self .lookup_qualified (fullname )
73167315 node = sym .node
7317- assert isinstance (node , TypeInfo )
7316+ assert isinstance (node , TypeInfo ), node
73187317 return node
73197318
73207319 def type_type (self ) -> Instance :
@@ -7905,6 +7904,9 @@ def has_valid_attribute(self, typ: Type, name: str) -> bool:
79057904 def get_expression_type (self , node : Expression , type_context : Type | None = None ) -> Type :
79067905 return self .expr_checker .accept (node , type_context = type_context )
79077906
7907+ def is_defined_in_stub (self , typ : Instance , / ) -> bool :
7908+ return self .modules [typ .type .module_name ].is_stub
7909+
79087910 def check_deprecated (self , node : Node | None , context : Context ) -> None :
79097911 """Warn if deprecated and not directly imported with a `from` statement."""
79107912 if isinstance (node , Decorator ):
0 commit comments