@@ -120,6 +120,8 @@ class FuzzResult:
120120 maybe_bug : MinimizedSourceCode | None
121121 # The executable we're testing
122122 executable : Executable
123+ _ : KW_ONLY
124+ only_new_bugs : bool
123125
124126 def print_description (self , index : int , num_seeds : int ) -> None :
125127 """Describe the results of fuzzing the parser with this seed."""
@@ -131,12 +133,16 @@ def print_description(self, index: int, num_seeds: int) -> None:
131133 )
132134 print (f"{ msg :<60} { progress :>15} " , flush = True )
133135
136+ new = "new " if self .only_new_bugs else ""
137+
134138 if self .maybe_bug :
135139 match self .executable :
136140 case Executable .RUFF :
137- panic_message = "The following code triggers a parser bug:"
141+ panic_message = f "The following code triggers a { new } parser bug:"
138142 case Executable .RED_KNOT :
139- panic_message = "The following code triggers a red-knot panic:"
143+ panic_message = (
144+ f"The following code triggers a { new } red-knot panic:"
145+ )
140146 case _ as unreachable :
141147 assert_never (unreachable )
142148
@@ -153,6 +159,7 @@ def fuzz_code(seed: Seed, args: ResolvedCliArgs) -> FuzzResult:
153159 minimizer_callback : Callable [[str ], bool ] | None = None
154160
155161 if args .baseline_executable_path is None :
162+ only_new_bugs = False
156163 if contains_bug (
157164 code , executable = args .executable , executable_path = args .test_executable_path
158165 ):
@@ -162,22 +169,24 @@ def fuzz_code(seed: Seed, args: ResolvedCliArgs) -> FuzzResult:
162169 executable = args .executable ,
163170 executable_path = args .test_executable_path ,
164171 )
165- elif contains_new_bug (
166- code ,
167- executable = args .executable ,
168- test_executable_path = args .test_executable_path ,
169- baseline_executable_path = args .baseline_executable_path ,
170- ):
171- bug_found = True
172- minimizer_callback = partial (
173- contains_new_bug ,
172+ else :
173+ only_new_bugs = True
174+ if contains_new_bug (
175+ code ,
174176 executable = args .executable ,
175177 test_executable_path = args .test_executable_path ,
176178 baseline_executable_path = args .baseline_executable_path ,
177- )
179+ ):
180+ bug_found = True
181+ minimizer_callback = partial (
182+ contains_new_bug ,
183+ executable = args .executable ,
184+ test_executable_path = args .test_executable_path ,
185+ baseline_executable_path = args .baseline_executable_path ,
186+ )
178187
179188 if not bug_found :
180- return FuzzResult (seed , None , args .executable )
189+ return FuzzResult (seed , None , args .executable , only_new_bugs = only_new_bugs )
181190
182191 assert minimizer_callback is not None
183192
@@ -194,14 +203,15 @@ def fuzz_code(seed: Seed, args: ResolvedCliArgs) -> FuzzResult:
194203 else :
195204 maybe_bug = MinimizedSourceCode (code )
196205
197- return FuzzResult (seed , maybe_bug , args .executable )
206+ return FuzzResult (seed , maybe_bug , args .executable , only_new_bugs = only_new_bugs )
198207
199208
200209def run_fuzzer_concurrently (args : ResolvedCliArgs ) -> list [FuzzResult ]:
201210 num_seeds = len (args .seeds )
202211 print (
203212 f"Concurrently running the fuzzer on "
204- f"{ num_seeds } randomly generated source-code files..."
213+ f"{ num_seeds } randomly generated source-code "
214+ f"file{ 's' if num_seeds != 1 else '' } ..."
205215 )
206216 bugs : list [FuzzResult ] = []
207217 with concurrent .futures .ProcessPoolExecutor () as executor :
@@ -229,7 +239,8 @@ def run_fuzzer_sequentially(args: ResolvedCliArgs) -> list[FuzzResult]:
229239 num_seeds = len (args .seeds )
230240 print (
231241 f"Sequentially running the fuzzer on "
232- f"{ num_seeds } randomly generated source-code files..."
242+ f"{ num_seeds } randomly generated source-code "
243+ f"file{ 's' if num_seeds != 1 else '' } ..."
233244 )
234245 bugs : list [FuzzResult ] = []
235246 for i , seed in enumerate (args .seeds , start = 1 ):
0 commit comments