@@ -832,20 +832,43 @@ def func1():
832832
833833 self .check_events (func1 , [("raise" , KeyError )])
834834
835- # gh-116090: This test doesn't really require specialization, but running
836- # it without specialization exposes a monitoring bug.
837- @requires_specialization
838835 def test_implicit_stop_iteration (self ):
836+ """Generators are documented as raising a StopIteration
837+ when they terminate.
838+ However, we don't do that if we can avoid it, for speed.
839+ sys.monitoring handles that by injecting a STOP_ITERATION
840+ event when we would otherwise have skip the RAISE event.
841+ This test checks that both paths record an equivalent event.
842+ """
839843
840844 def gen ():
841845 yield 1
842846 return 2
843847
844- def implicit_stop_iteration ():
845- for _ in gen ():
848+ def implicit_stop_iteration (iterator = None ):
849+ if iterator is None :
850+ iterator = gen ()
851+ for _ in iterator :
846852 pass
847853
848- self .check_events (implicit_stop_iteration , [("raise" , StopIteration )], recorders = (StopiterationRecorder ,))
854+ recorders = (ExceptionRecorder , StopiterationRecorder ,)
855+ expected = [("raise" , StopIteration )]
856+
857+ # Make sure that the loop is unspecialized, and that it will not
858+ # re-specialize immediately, so that we can we can test the
859+ # unspecialized version of the loop first.
860+ # Note: this assumes that we don't specialize loops over sets.
861+ implicit_stop_iteration (set (range (100 )))
862+
863+ # This will record a RAISE event for the StopIteration.
864+ self .check_events (implicit_stop_iteration , expected , recorders = recorders )
865+
866+ # Now specialize, so that we see a STOP_ITERATION event.
867+ for _ in range (100 ):
868+ implicit_stop_iteration ()
869+
870+ # This will record a STOP_ITERATION event for the StopIteration.
871+ self .check_events (implicit_stop_iteration , expected , recorders = recorders )
849872
850873 initial = [
851874 ("raise" , ZeroDivisionError ),
0 commit comments