Issue 33323: inconsistent stack trace for exceptions thrown in generators passed to min/max (original) (raw)
Issue33323
Created on 2018-04-21 10:53 by Naris R, last changed 2022-04-11 14:58 by admin. This issue is now closed.
Messages (4) | ||
---|---|---|
msg315561 - (view) | Author: Naris R (Naris R) * | Date: 2018-04-21 10:53 |
if a generator passed to min/max throws an exception, the stack trace is normally shown on the line that caused the exception, but if the exception is a StopIteration, the trace only shows the line where the max/min function was called. I was writing a minimax and alphabeta search with generator expression and list comprehension and accidentally passed an empty iterator to the next function while computing states for minimax and it took a very long time to find out where the error was actually caused. | ||
msg315568 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * ![]() |
Date: 2018-04-21 13:06 |
Could you please provide a sample code? | ||
msg315569 - (view) | Author: Naris R (Naris R) * | Date: 2018-04-21 13:19 |
This is a little bit contrived but it demonstrates the problem. ``` def good_exception(): raise Exception('something bad happened') def bad_exception(): return next(iter([])) def good(n): return good_exception() + n def bad(n): return n - bad_exception() import traceback try: max(good(i) for i in range(4)) # desirable behaviour except: traceback.print_exc() try: min(bad(i) for i in range(7)) # unhelpful error message except: traceback.print_exc() ``` | ||
msg315571 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * ![]() |
Date: 2018-04-21 15:19 |
In Python 2.7 and 3.6 I got the following traceback for the second case: Traceback (most recent call last): File ".py", line 21, in min(bad(i) for i in range(7)) # unhelpful error message ValueError: max() arg is an empty sequence StopIteration in generator expressions didn't treated as an error. It just stopped the iteration. The exception is raised by the consumer of generated values, min(), because it doesn't work with empty sequences by default. This behavior caused hard to investigate bugs and was considered harmful. Fortunately it will be fixed in Python 3.7. The traceback in 3.7: Traceback (most recent call last): File ".py", line 21, in min(bad(i) for i in range(7)) # unhelpful error message File ".py", line 11, in bad return n - bad_exception() File ".py", line 5, in bad_exception return next(iter([])) StopIteration The above exception was the direct cause of the following exception: Traceback (most recent call last): File ".py", line 21, in min(bad(i) for i in range(7)) # unhelpful error message RuntimeError: generator raised StopIteration You can enable this behavior in earlier versions (3.5+) by adding the future import: from __future__ import generator_stop See PEP 479 for details. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:58:59 | admin | set | github: 77504 |
2018-04-21 15:19:08 | serhiy.storchaka | set | status: open -> closedmessages: + components: + Interpreter Coreresolution: out of datestage: resolved |
2018-04-21 13:19:47 | Naris R | set | messages: + |
2018-04-21 13:06:31 | serhiy.storchaka | set | nosy: + serhiy.storchakamessages: + |
2018-04-21 10:53:20 | Naris R | create |