Skip to content
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

Inconsistent Unpacking Value Error Messages: Too Many Values to Unpack (Expected X) #128660

Closed
prasannaba opened this issue Jan 9, 2025 · 5 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement

Comments

@prasannaba
Copy link

prasannaba commented Jan 9, 2025

Feature or enhancement

Proposal:

Inconsistent Unpacking Error Messages: Too Many Values to Unpack (Expected X)

Description:
When attempting to unpack values from a sequence (e.g., dictionary keys or a tuple), Python sometimes raises a ValueError that is misleading and could be clarified. The current error messages are inconsistent, which can cause confusion for users. Specifically, the error message "too many values to unpack (expected X)" is raised in two different unpacking situations, and this wording is not intuitive.

Problem:
Python raises the error message "too many values to unpack (expected X)" in cases where:

  1. The number of variables exceeds the number of values in the sequence.
  2. The number of values exceeds the number of variables, but Python raises the same error.

The problem is that the error message "too many values to unpack" implies that there are more values than variables, but it's actually the reverse in some cases. This can be confusing because the error message doesn't explicitly describe the issue—whether it's too many variables or not enough values.

Examples:

  1. Unpacking a Dictionary's Keys:

    counters = {'pumpernickel': 2, 'sourdough': 1}
    for i, j in counters.keys():
        print(i)

    Expected Behavior:

    • We are trying to unpack single values (the keys) into two variables.
    • The error message says: ValueError: too many values to unpack (expected 2)

    Explanation of Issue:

    • The error message is misleading. There is only one value (the string key) to unpack, but two variables (i and j) are expected.
    • The correct error message should be something like: "Too many variables to unpack into" or "Not enough values to unpack".
  2. Unpacking a Tuple with More Values than Variables:

    my_tuple = (1, 2, 3)
    a, b = my_tuple

    Expected Behavior:

    • We are trying to unpack three values into two variables.
    • The error message says: ValueError: too many values to unpack (expected 2)

    Explanation of Issue:

    • While this error message is closer to the actual issue (too many values for the given variables), the phrasing is still somewhat unclear. A more precise message could be: "Not enough variables to unpack".

Suggested Fix:

  1. Improve the Error Message for Case 1:

    • Instead of "too many values to unpack", when unpacking single values into multiple variables (as in the dictionary key case), the message could be:
      • "Too many variables to unpack into" or
      • "Not enough values to unpack".
  2. Clarify the Error Message for Case 2:

    • For the case where there are more values than variables (like unpacking a tuple), the message could be more precise:
      • "Not enough variables to unpack".

Additional Notes:

  • Both cases involve the same error message ("too many values to unpack"), but the underlying issues are different.
  • The current error message could be misleading because it doesn't clearly convey whether the issue is due to an excess of variables or values, making it harder for beginners (or even advanced users) to troubleshoot.
  • More precise error messages would improve Python's usability, particularly for users who are new to the language or unfamiliar with unpacking.

Steps to Reproduce:

  1. Create a dictionary or tuple (as shown in the examples).
  2. Try unpacking the elements into a mismatched number of variables (either more variables or fewer values).
  3. Observe the error message generated.

Environment:

  • Python Version: 3.12.8
  • Operating System: Ubuntu 24.04.1 LTS

Disclosure:

I have taken help from OpenAI's ChatGPT to intuitively understand Python error messages and in making this report while going through _Brett Slatkin's Effective Python (2nd edition)_ book. The dictionary counters is from the book, the for loop is my own and my_tuple as well as the report content (review and some modifications by me) are from ChatGPT. Python's error messages could be improved for better clarity, and a review to make them more intuitive would be beneficial.

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

@prasannaba prasannaba added the type-feature A feature request or enhancement label Jan 9, 2025
@picnixz
Copy link
Member

picnixz commented Jan 10, 2025

We recently improved those message sin #122244. Can you check with Python 3.14 to see if those new messages are now better?

@picnixz picnixz added interpreter-core (Objects, Python, Grammar, and Parser dirs) pending The issue will be closed if no feedback is provided labels Jan 10, 2025
@picnixz
Copy link
Member

picnixz commented Jan 10, 2025

Concerning the exact failures:

The error message says: ValueError: too many values to unpack (expected 2)

Actually, it's correct. The are too many values to unpack (1,2, 3) but we only have two destination variables. What you unpack is the tuple.

ValueError: too many values to unpack (expected 2)

Same here. keys() returns a string which you can unpack and behaves as a sequence (so you need as many destination variables as the length of string to have no error).

@prasannaba
Copy link
Author

prasannaba commented Jan 16, 2025

Thank you, Bénédikt Tran. As per your feedback, I checked the code with 3.14. I checked with both 3.14.0.a3 (before 3.14.0.0a4 was released) and 3.14.0.a4 versions of Python. The messages have been improved. Please see the attached image for my observations. I think, in case an attempt is made to unpack a single value into multiple variables, the message can be improved to "expected X, got 1."

Image

@picnixz
Copy link
Member

picnixz commented Jan 18, 2025

Concerning this error message, it is actually correct. A string is iterable and thus can be unpacked.

for i, j in counter.keys(): ...

is equivalent to

for key in counter.keys():
    i, j = key
    ...

And i, j = key is equivalent to unpack a string key into two variables. It would only work if key has length 2. I don't think we should specialize the error message for strings as they would likely be misunderstood (we would need "expected 2, got len(key)" and not "got 1"

@picnixz
Copy link
Member

picnixz commented Feb 4, 2025

Considering the weird case with strings is actually working as expected and that error messages were improved in 3.14, I'll close this one as wont fix.

@picnixz picnixz closed this as not planned Won't fix, can't repro, duplicate, stale Feb 4, 2025
@picnixz picnixz removed the pending The issue will be closed if no feedback is provided label Feb 4, 2025
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

2 participants