To put it simple, unpacking raises ValueError:
x, = () Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: not enough values to unpack (expected 1, got 0) x, = (1, 2) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: too many values to unpack (expected 1)
But if the iterator raises ValueError, there's no way to tell it apart from the unpacking:
def foo(): ... yield None ... raise ValueError ... foo()
x = foo() x, = foo() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in foo ValueError
And the workaround for this is a bit ugly. We already convert e.g. StopIteration into RuntimeError in many cases, why can't we do so here too? For backwards compatibility, this should probably be an itertools utility tho.