the problem here is that "iterable unpacking" (is that what we call it now?) is pretty general, and used all over python. In the example given, it seemed that that would be a helpful message, but it wouldn't really solve the general problem: that is, that dicts iterate over keys, and people sometimes forget and expect that they are iteration go over the items. but if your keys happen to be length-2 iterables, then you won't get an error -- but you will also not get what is likely expected:

In [3]: d = {"ab": 123,
   ...:      "cd": 345}                                                        

In [4]: for string, number in d:
   ...:     print(string, number)
a b
c d


So, in the general case how helpful is it to provide the type of what is being unpacked??

(and note that in this case, I (key, value) tuple is expected, and a tuple is a perfectly valid dict key, too, so again, type isn't necessarily helpful. Length would be a bit more helpful, but still not always.

That being said, more information is better than less, so maybe an unpacking error should show the *value* of what was being unpacked:

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

Which, in fact, is what iPython already does:

In [5]: a,b = 1,2,3                                                            
ValueError                                Traceback (most recent call last)
<ipython-input-5-402193b14bdc> in <module>
----> 1 a,b = 1,2,3

ValueError: too many values to unpack (expected 2)

But not in the dict iterating case:

In [2]: for key, val in d:
   ...:     print(key, val)
ValueError                                Traceback (most recent call last)
<ipython-input-2-8ac4fd3a14a8> in <module>
----> 1 for key, val in d:
      2     print(key, val)

ValueError: too many values to unpack (expected 2)

(cause it's showing the line of code, not the run time values)

So if possible, it would be great if error messages did generally show the value(s) of the objects involved, if possible.

Then that would be:

ValueError: too many values to unpack (expected 2, got : 'this')

Given that it's a ValueError, it seem the *value* should be known, and generally relevant.

And this is already done for some ValueErrors:

In [3]: i = int('45f')                                                          
ValueError                                Traceback (most recent call last)
<ipython-input-3-45f7234bd5b5> in <module>
----> 1 i = int('45f')

ValueError: invalid literal for int() with base 10: '45f'

Maybe it should be for ALL Value Errors? 


On Sun, Mar 1, 2020 at 11:38 AM Alex Hall <> wrote:
IIRC, the new unpacking code still works like the old in that it special-cases list and tuple (where it can use the fast indexing API that just accesses the C array underneath), but for everything else it calls a function with iter(obj). If so, adding the length for list and tuple would be trivial, but adding it for other builtin types would not.

Is list and tuple good enough? It won’t help your example use, where it’s str, but I think for that case you don’t generally care that the string had 6 chars instead of 2; you already know the problem from it being a string in the first place. I suspect that almost every time the type is right but the length isn’t, the type is list, tuple, or a non-builtin type. How often do you accidentally unpack a length-6 dict where you wanted to unpack a length-2 dict?

I agree with all of this, and I think this is a great balance of implementation complexity and value, especially when the code already accounts for it.

I've made an issue here:
Python-ideas mailing list --
To unsubscribe send an email to
Message archived at
Code of Conduct:

Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython