Misleading error message of the day

Discussion in 'Python' started by Roy Smith, Dec 8, 2011.

  1. Roy Smith

    Roy Smith Guest

    I just spent a while beating my head against this one.

    # Python 2.6
    >>> a, b = 'foo'

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

    The real problem is that there's too *few* values to unpack! It should
    have been

    a, b = 'foo', 'bar'

    I understand why it's generating the exception it does (the string is an
    iterable), but man, did that message throw off my thought processes and
    lead me down some totally bogus debugging paths.

    It's an unusual case to want to unpack a string. Maybe the message
    should changed to "too {many, few} values to unpack (are you sure you
    wanted to unpack a string?)" if the RHS is a basestring?
     
    Roy Smith, Dec 8, 2011
    #1
    1. Advertising

  2. On 12/08/2011 02:23 PM, Roy Smith wrote:
    > I just spent a while beating my head against this one.
    >
    > # Python 2.6
    >>>> a, b = 'foo'

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in<module>
    > ValueError: too many values to unpack
    >
    > The real problem is that there's too *few* values to unpack! It should
    > have been
    >
    > a, b = 'foo', 'bar'
    >
    > I understand why it's generating the exception it does (the string is an
    > iterable), but man, did that message throw off my thought processes and
    > lead me down some totally bogus debugging paths.
    >
    > It's an unusual case to want to unpack a string. Maybe the message
    > should changed to "too {many, few} values to unpack (are you sure you
    > wanted to unpack a string?)" if the RHS is a basestring?


    I had a few errors sometimes because I thought I passed in a list while
    I passed only a string, which since it's still iterable would just work
    but explode later.

    A nicer message wouldn't have really actually helped though, not sure
    it's worth to make an exception for such a thing..
     
    Andrea Crotti, Dec 8, 2011
    #2
    1. Advertising

  3. On Fri, Dec 9, 2011 at 1:23 AM, Roy Smith <> wrote:
    > I just spent a while beating my head against this one.
    >
    > # Python 2.6
    >>>> a, b = 'foo'

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


    Definitely weird! I smell a job for a linter though. If you had just
    happened to have a two-character string there, it would have quietly
    succeeded, and left you wondering what was going on - imho rather
    worse.

    This isn't something for the language to solve; the same issue would
    come up if you had something like:

    a=[1,2,3]
    b=[4,5,6]

    c,d=a # oops, mucked up the "a,b" side

    Or any other iterable. Looks to me like a chance for an informational
    note from your lint facility, not a change to the language.

    ChrisA
     
    Chris Angelico, Dec 8, 2011
    #3
  4. Roy Smith

    Robert Kern Guest

    On 12/8/11 2:23 PM, Roy Smith wrote:
    > I just spent a while beating my head against this one.
    >
    > # Python 2.6
    >>>> a, b = 'foo'

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in<module>
    > ValueError: too many values to unpack
    >
    > The real problem is that there's too *few* values to unpack! It should
    > have been
    >
    > a, b = 'foo', 'bar'
    >
    > I understand why it's generating the exception it does (the string is an
    > iterable), but man, did that message throw off my thought processes and
    > lead me down some totally bogus debugging paths.
    >
    > It's an unusual case to want to unpack a string. Maybe the message
    > should changed to "too {many, few} values to unpack (are you sure you
    > wanted to unpack a string?)" if the RHS is a basestring?


    Would including the respective numbers help your thought processes?

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

    --
    Robert Kern

    "I have come to believe that the whole world is an enigma, a harmless enigma
    that is made terrible by our own mad attempt to interpret it as though it had
    an underlying truth."
    -- Umberto Eco
     
    Robert Kern, Dec 8, 2011
    #4
  5. Roy Smith wrote:
    > I just spent a while beating my head against this one.
    >
    > # Python 2.6
    >
    >>>> a, b = 'foo'
    >>>>

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in <module>
    > ValueError: too many values to unpack
    >
    > The real problem is that there's too *few* values to unpack! It should
    > have been
    >
    > a, b = 'foo', 'bar'
    >
    > I understand why it's generating the exception it does (the string is an
    > iterable), but man, did that message throw off my thought processes and
    > lead me down some totally bogus debugging paths.
    >
    > It's an unusual case to want to unpack a string. Maybe the message
    > should changed to "too {many, few} values to unpack (are you sure you
    > wanted to unpack a string?)" if the RHS is a basestring?
    >

    string are iterable, considering this, the error is correct.

    Values to unpack in 'foo' are 'f', 'o', 'o'

    > a,b,c = 'foo'


    > print a,b,c

    f o o


    JM
     
    Jean-Michel Pichavant, Dec 8, 2011
    #5
  6. Am 08.12.2011 15:47, schrieb Robert Kern:
    > Would including the respective numbers help your thought processes?
    > ValueError: too many values to unpack (expected 2, got 3)


    Not possible in the general case (as the right-hand side might be an
    arbitrary iterable/iterator...).

    --
    --- Heiko.
     
    Heiko Wundram, Dec 8, 2011
    #6
  7. Roy Smith

    Roy Smith Guest

    On Thursday, December 8, 2011 9:47:02 AM UTC-5, Robert Kern wrote:

    > Would including the respective numbers help your thought processes?
    >
    > ValueError: too many values to unpack (expected 2, got 3)


    I don't know if that would have done the trick for me on this particular one. On the other hand, adding "expected X, got Y" to the message would generally be a good thing.
     
    Roy Smith, Dec 8, 2011
    #7
  8. Roy Smith

    Roy Smith Guest

    On Thursday, December 8, 2011 9:47:02 AM UTC-5, Robert Kern wrote:

    > Would including the respective numbers help your thought processes?
    >
    > ValueError: too many values to unpack (expected 2, got 3)


    I don't know if that would have done the trick for me on this particular one. On the other hand, adding "expected X, got Y" to the message would generally be a good thing.
     
    Roy Smith, Dec 8, 2011
    #8
  9. Roy Smith

    Roy Smith Guest

    On Thursday, December 8, 2011 10:03:38 AM UTC-5, Jean-Michel Pichavant wrote:
    > string are iterable, considering this, the error is correct.


    Yes, I understand that the exception is correct. I'm not saying the exception should be changed, just that we have the opportunity to produce a more useful error message. The exception would be equally correct if it was:

    ValueError: you did something wrong

    but most people would probably agree that it's not the most useful message that could have been produced.
     
    Roy Smith, Dec 8, 2011
    #9
  10. Roy Smith

    Roy Smith Guest

    On Thursday, December 8, 2011 10:03:38 AM UTC-5, Jean-Michel Pichavant wrote:
    > string are iterable, considering this, the error is correct.


    Yes, I understand that the exception is correct. I'm not saying the exception should be changed, just that we have the opportunity to produce a more useful error message. The exception would be equally correct if it was:

    ValueError: you did something wrong

    but most people would probably agree that it's not the most useful message that could have been produced.
     
    Roy Smith, Dec 8, 2011
    #10
  11. Roy Smith

    Roy Smith Guest

    On Thursday, December 8, 2011 10:16:56 AM UTC-5, Heiko Wundram wrote:
    > Am 08.12.2011 15:47, schrieb Robert Kern:
    > > Would including the respective numbers help your thought processes?
    > > ValueError: too many values to unpack (expected 2, got 3)

    >
    > Not possible in the general case (as the right-hand side might be an
    > arbitrary iterable/iterator...).


    Why not? Take this example:

    def i():
    i = 0
    while True:
    print "returning:", i
    yield i
    i += 1

    a, b = i()

    ../iter.py
    returning: 0
    returning: 1
    returning: 2
    Traceback (most recent call last):
    File "./iter.py", line 10, in <module>
    a, b = i()
    ValueError: too many values to unpack

    The exception was raised when i() returned it's third value, so saying "expected 2, got 3" is exactly correct. Yes, it is true that it might have gotten more if it kept going, but that's immaterial; the fact that it got to 3is what caused the Holy Hand Grenade to be thrown.
     
    Roy Smith, Dec 8, 2011
    #11
  12. Roy Smith

    Roy Smith Guest

    On Thursday, December 8, 2011 10:16:56 AM UTC-5, Heiko Wundram wrote:
    > Am 08.12.2011 15:47, schrieb Robert Kern:
    > > Would including the respective numbers help your thought processes?
    > > ValueError: too many values to unpack (expected 2, got 3)

    >
    > Not possible in the general case (as the right-hand side might be an
    > arbitrary iterable/iterator...).


    Why not? Take this example:

    def i():
    i = 0
    while True:
    print "returning:", i
    yield i
    i += 1

    a, b = i()

    ../iter.py
    returning: 0
    returning: 1
    returning: 2
    Traceback (most recent call last):
    File "./iter.py", line 10, in <module>
    a, b = i()
    ValueError: too many values to unpack

    The exception was raised when i() returned it's third value, so saying "expected 2, got 3" is exactly correct. Yes, it is true that it might have gotten more if it kept going, but that's immaterial; the fact that it got to 3is what caused the Holy Hand Grenade to be thrown.
     
    Roy Smith, Dec 8, 2011
    #12
  13. Am 08.12.2011 16:42, schrieb Roy Smith:
    > The exception was raised when i() returned it's third value, so saying "expected 2, got 3" is exactly correct. Yes, it is true that it might have gotten more if it kept going, but that's immaterial; the fact that it got to 3 is what caused the Holy Hand Grenade to be thrown.


    Please explain how that error message (in case you're not aiming at the
    actual count of elements in the source) differs from the curent wording
    "too many values", as you're simply displaying "expected n, got n+1"
    where n is visible from the immediate exception output...

    --
    --- Heiko.
     
    Heiko Wundram, Dec 8, 2011
    #13
  14. On 12/08/2011 03:42 PM, Roy Smith wrote:
    >
    > Why not? Take this example:
    >
    > def i():
    > i = 0
    > while True:
    > print "returning:", i
    > yield i
    > i += 1
    >
    > a, b = i()
    >
    > ./iter.py
    > returning: 0
    > returning: 1
    > returning: 2
    > Traceback (most recent call last):
    > File "./iter.py", line 10, in<module>
    > a, b = i()
    > ValueError: too many values to unpack
    >
    > The exception was raised when i() returned it's third value, so saying "expected 2, got 3" is exactly correct. Yes, it is true that it might have gotten more if it kept going, but that's immaterial; the fact that it got to 3 is what caused the Holy Hand Grenade to be thrown.


    Yes but how do you know how many values you generated when it quits?
    I mean I don't know how it work internally, but it should keep a temporary
    list of the yielded values to be able to find out how many values are
    there..
     
    Andrea Crotti, Dec 8, 2011
    #14
  15. On Fri, Dec 9, 2011 at 2:55 AM, Andrea Crotti <> wrote:
    > Yes but how do you know how many values you generated when it quits?
    > I mean I don't know how it work internally, but it should keep a temporary
    > list of the yielded values to be able to find out how many values are
    > there..


    Iterator unpacking works roughly thus:

    1) Count up how many results you need (call that N)
    2) N times, get a value from the iterator. If StopIteration is raised,
    swallow it and raise ValueError because there were too few values.
    3) Attempt to get one more value from the iterator. If StopIteration
    is NOT raised, raise ValueError because there were too many values.

    At no point is the "total size" of the iterator counted (it could,
    after all, be infinite). When ValueError is raised, all that's known
    is that StopIteration wasn't raised at the end of the process.

    ChrisA
     
    Chris Angelico, Dec 8, 2011
    #15
  16. Roy Smith

    Tim Chase Guest

    On 12/08/11 09:30, Roy Smith wrote:
    > On Thursday, December 8, 2011 9:47:02 AM UTC-5, Robert Kern
    > wrote:
    >
    >> Would including the respective numbers help your thought
    >> processes?
    >>
    >> ValueError: too many values to unpack (expected 2, got 3)

    >
    > I don't know if that would have done the trick for me on this
    > particular one. On the other hand, adding "expected X, got Y"
    > to the message would generally be a good thing.


    given the nature of the message, and the interaction with
    iterators-of-arbitrary/infinite length, it might have to be
    reduced to

    "Expected N, got more"

    or for the case where you didn't get enough, you know how many
    you got: "Expected N, but only got M". But the extra information
    would certainly be useful in tracking it down.

    -tkc
     
    Tim Chase, Dec 8, 2011
    #16
  17. On 2011-12-08, Roy Smith <> wrote:
    > On Thursday, December 8, 2011 10:03:38 AM UTC-5, Jean-Michel Pichavant wrote:
    >> string are iterable, considering this, the error is correct.

    >
    > Yes, I understand that the exception is correct. I'm not saying the exception should be changed, just that we have the opportunity to produce a more useful error message. The exception would be equally correct if it was:
    >
    > ValueError: you did something wrong


    My favorite is still the old classic error from and old Unix printer
    port driver:

    "lp0 on fire"

    > but most people would probably agree that it's not the most useful
    > message that could have been produced.


    --
    Grant Edwards grant.b.edwards Yow! Don't hit me!! I'm in
    at the Twilight Zone!!!
    gmail.com
     
    Grant Edwards, Dec 8, 2011
    #17
  18. Roy Smith

    Roy Smith Guest

    (some,
    very,
    long,
    list,
    of,
    variable,
    names,
    to,
    get,
    the,
    stuff,
    unpacked,
    into) = function_that_should_return_a_14_tuple()

    raises

    ValueError: too many values to unpack

    Quick, what's the bug? Did I forget a variable on the LHS, or is my function returning more things than it should? I know it's supposed to be 14, but I don't know which side is wrong. Had it said "... expected 13, got 14", I would know immediately.

    Error messages should be as explicit as possible. It's just like bug reports. The basic mantra of a bug report is:

    1) This is what I did

    2) This is what I expected to happen

    3) This is what I observed happen

    4) This is how what I observed differed from what I expected

    Saying, "expected X, got Y" is more explicit than "got too many"
     
    Roy Smith, Dec 8, 2011
    #18
  19. Roy Smith

    Roy Smith Guest

    (some,
    very,
    long,
    list,
    of,
    variable,
    names,
    to,
    get,
    the,
    stuff,
    unpacked,
    into) = function_that_should_return_a_14_tuple()

    raises

    ValueError: too many values to unpack

    Quick, what's the bug? Did I forget a variable on the LHS, or is my function returning more things than it should? I know it's supposed to be 14, but I don't know which side is wrong. Had it said "... expected 13, got 14", I would know immediately.

    Error messages should be as explicit as possible. It's just like bug reports. The basic mantra of a bug report is:

    1) This is what I did

    2) This is what I expected to happen

    3) This is what I observed happen

    4) This is how what I observed differed from what I expected

    Saying, "expected X, got Y" is more explicit than "got too many"
     
    Roy Smith, Dec 8, 2011
    #19
  20. On Thu, Dec 8, 2011 at 1:42 PM, Roy Smith <> wrote:
    > (some,
    >  very,
    >  long,
    >  list,
    >  of,
    >  variable,
    >  names,
    >  to,
    >  get,
    >  the,
    >  stuff,
    >  unpacked,
    >  into) = function_that_should_return_a_14_tuple()
    >
    > raises
    >
    > ValueError: too many values to unpack
    >
    > Quick, what's the bug?  Did I forget a variable on the LHS, or is my function returning more things than it should?  I know it's supposed to be 14, but I don't know which side is wrong.  Had it said "... expected 13, got 14", I would know immediately.
    >


    If the RHS was a tuple or a list, yes you could know immediately. But
    unpacking works with any iterable, so it probably doesn't special-case
    lists and tuples. Iterables don't have a size- they just keep going
    until StopIteration is raised. So in EVERY SINGLE CASE, you would get
    "expected n args, got n+1" even if the iterable would return 24 items
    instead of 14, or would never stop returning items.


    > Error messages should be as explicit as possible.  It's just like bug reports.  The basic mantra of a bug report is:
    >
    > 1) This is what I did
    >
    > 2) This is what I expected to happen
    >
    > 3) This is what I observed happen
    >
    > 4) This is how what I observed differed from what I expected
    >
    > Saying, "expected X, got Y" is more explicit than "got too many"
    >
    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list
     
    Benjamin Kaplan, Dec 8, 2011
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. j
    Replies:
    5
    Views:
    425
    Samuel Barber
    Jul 27, 2003
  2. Brian Kelley

    Misleading Python error message

    Brian Kelley, Nov 19, 2003, in forum: Python
    Replies:
    4
    Views:
    378
    Dennis Lee Bieber
    Nov 21, 2003
  3. Claudio Grondi
    Replies:
    8
    Views:
    808
    Georg Brandl
    Aug 28, 2006
  4. Erik Johnson
    Replies:
    4
    Views:
    367
  5. Andy
    Replies:
    1
    Views:
    754
Loading...

Share This Page