@@ -487,6 +487,8 @@ def __init__(
487487 # Used to track whether currently inside an except* block. This helps
488488 # to invoke errors when continue/break/return is used inside except* block.
489489 self .inside_except_star_block : bool = False
490+ # Used to track edge case when return is still inside except* if it enters a loop
491+ self .return_stmt_inside_except_star_block : bool = False
490492
491493 # mypyc doesn't properly handle implementing an abstractproperty
492494 # with a regular attribute so we make them properties
@@ -516,13 +518,23 @@ def allow_unbound_tvars_set(self) -> Iterator[None]:
516518 self .allow_unbound_tvars = old
517519
518520 @contextmanager
519- def inside_except_star_block_set (self , value : bool ) -> Iterator [None ]:
521+ def inside_except_star_block_set (
522+ self , value : bool , enteringLoop : bool = False
523+ ) -> Iterator [None ]:
520524 old = self .inside_except_star_block
521525 self .inside_except_star_block = value
526+
527+ # Return statement would still be in except* scope if entering loops
528+ if not enteringLoop :
529+ old_return_stmt_flag = self .return_stmt_inside_except_star_block
530+ self .return_stmt_inside_except_star_block = value
531+
522532 try :
523533 yield
524534 finally :
525535 self .inside_except_star_block = old
536+ if not enteringLoop :
537+ self .return_stmt_inside_except_star_block = old_return_stmt_flag
526538
527539 #
528540 # Preparing module (performed before semantic analysis)
@@ -890,7 +902,7 @@ def visit_func_def(self, defn: FuncDef) -> None:
890902 return
891903
892904 with self .scope .function_scope (defn ):
893- with self .inside_except_star_block_set (False ):
905+ with self .inside_except_star_block_set (value = False ):
894906 self .analyze_func_def (defn )
895907
896908 def function_fullname (self , fullname : str ) -> str :
@@ -5277,7 +5289,7 @@ def visit_return_stmt(self, s: ReturnStmt) -> None:
52775289 self .statement = s
52785290 if not self .is_func_scope ():
52795291 self .fail ('"return" outside function' , s )
5280- if self .inside_except_star_block :
5292+ if self .return_stmt_inside_except_star_block :
52815293 self .fail ('"return" not allowed in except* block' , s , serious = True , blocker = True )
52825294 if s .expr :
52835295 s .expr .accept (self )
@@ -5312,7 +5324,7 @@ def visit_while_stmt(self, s: WhileStmt) -> None:
53125324 self .statement = s
53135325 s .expr .accept (self )
53145326 self .loop_depth [- 1 ] += 1
5315- with self .inside_except_star_block_set (False ):
5327+ with self .inside_except_star_block_set (value = False , enteringLoop = True ):
53165328 s .body .accept (self )
53175329 self .loop_depth [- 1 ] -= 1
53185330 self .visit_block_maybe (s .else_body )
@@ -5337,7 +5349,7 @@ def visit_for_stmt(self, s: ForStmt) -> None:
53375349 s .index_type = analyzed
53385350
53395351 self .loop_depth [- 1 ] += 1
5340- with self .inside_except_star_block_set (False ):
5352+ with self .inside_except_star_block_set (value = False , enteringLoop = True ):
53415353 self .visit_block (s .body )
53425354 self .loop_depth [- 1 ] -= 1
53435355 self .visit_block_maybe (s .else_body )
0 commit comments