Skip to content

Improve error message for unbalanced unpacking #122239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tusharsadhwani opened this issue Jul 24, 2024 · 6 comments
Closed

Improve error message for unbalanced unpacking #122239

tusharsadhwani opened this issue Jul 24, 2024 · 6 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement

Comments

@tusharsadhwani
Copy link
Contributor

tusharsadhwani commented Jul 24, 2024

Feature or enhancement

Proposal:

This is great:

>>> x, y, z = 1, 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 2)

But here, it doesn't seem to tell how many values were found:

>>> x, y, z = 1, 2, 3, 4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)

I was hoping to see (expected 3, got 4) here. The eval loop also seems to have access to an entire PyList object at this point, so getting its length for the error message should not cause any changes in behaviour.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs

@tusharsadhwani tusharsadhwani added the type-feature A feature request or enhancement label Jul 24, 2024
@HarryLHW
Copy link
Contributor

HarryLHW commented Jul 24, 2024

If the right hand side is an iterator, it will consume more elements of the iterator than before, e.g.

>>> a = iter(range(100))
>>> x, y, z = a
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    x, y, z = a
    ^^^^^^^
ValueError: too many values to unpack (expected 3)
>>> next(a)  # instead of StopIteration
4 
>>> 

@tusharsadhwani
Copy link
Contributor Author

tusharsadhwani commented Jul 24, 2024

I see! Would it be possible to only add the length for Sequence / Sized types?

@hugovk hugovk added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Jul 24, 2024
@tusharsadhwani
Copy link
Contributor Author

tusharsadhwani commented Jul 24, 2024

Also, isn't the current behaviour also slightly undesirable? the iterator had 4 values consumed from it, instead of 3. Is this behaviour to be depended upon? As in, should programs depend on the behaviour that if an unbalanced unpacking happens, N+1 items will be consumed?

(These are genuine questions, this is my first time trying to reason about the interals of the eval loop.)

@tusharsadhwani
Copy link
Contributor Author

OK thinking more about this, if it's an infinite iterator you definitely don't want to be stuck forever here.

@Eclips4
Copy link
Member

Eclips4 commented Jul 24, 2024

OK thinking more about this, if it's an infinite iterator you definitely don't want to be stuck forever here.

You're right - we need to know how many values are on the right side. But if we have infinity iterator on the right, it will take forever. So, unfortunately, there's no way to do this, even though the idea is good. :( I think we should close this issue.

@tusharsadhwani
Copy link
Contributor Author

We can't do something like?

if (PySequence_Check(v)) {
    ll = PySequence_Size(v);
    _PyErr_Format(tstate, PyExc_ValueError,
                "too many values to unpack (expected %d, got %d)",
                argcnt, ll);
} else {
    _PyErr_Format(tstate, PyExc_ValueError,
                "too many values to unpack (expected %d)",
                argcnt);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

5 participants