ValueError: need more than 2 values to unpack in Python 2.6.6
i am getting error: ValueError: need more than 2 values to unpack when i run the unit test now, so 2 failures and one skip now as far as i have read about
lambda i: get_error_count(self._error_lookup, i))
line 142 of source is the method
for test, err, capt in errors:
which has the line of code:
count = get_error_count(i)
reference Python 3.0 has something a bit like this. Excess values can be bound (as a list) to the last variable:
a,b,*c = [1,2,3,4,5]
will result in c containing [3,4,5].
In Python 2.x, you can't do that directly, but you should be able to create a function that lengthens or shortens an input tuple of arguments to the correct length so you can do:
a,c,b = fix(1,2) d,e,f = fix(1,2,3,4)
However, the function won't know the length of the left hand side sequence, so it will have to be passed in as an extra parameter or hard coded.
so the
count = get_error_count(i) uses only one variable, where as def get_error_count(lookup, index): takes on 2
What should i use as the second variable ? to fix this ?
Thanks, -Kamal.
-------------------- >> begin captured stdout << ---------------------
\ test_many_errors.test_assert_one ... FAIL test_many_errors.test_one ... ok test_many_errors.test_assert_two ... ERROR test_many_errors.test_two ... ok test_many_errors.test_value_one ... ERROR test_many_errors.test_value_two ... SKIP: (, ValueError(), ) test_many_errors.test_good_one ... ok test_many_errors.test_good_two ... ok
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/Current/bin/nosetests", line 10, in <module>
sys.exit(run_exit())
File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/site-packages/nose/core.py", line 117, in __init__
**extra_args)
File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/unittest.py", line 817, in __init__
self.runTests()
File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/site-packages/nose/core.py", line 196, in runTests
result = self.testRunner.run(self.test)
File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/site-packages/nose/core.py", line 63, in run
result.printErrors()
File "/NOSE_TRIM/nosetrim-read-only/nosetrim/nosetrim.py", line 136, in printErrors
lambda i: get_error_count(self._error_lookup, i))
File "/NOSE_TRIM/nosetrim-read-only/nosetrim/nosetrim.py", line 142, in printErrorList
for test, err, capt in errors:
ValueError: need more than 2 values to unpack
/
--------------------- >> end captured stdout << ----------------------
Ran 3 tests in 1.263s
Instead of unpacking in your assignment:
a, b, c = do_something()
Try assigning the result to a single variable and testing its length:
t = do_something()
# t is now a tuple (or list, or whatever was returned) of results
if len(t) > 2:
# Can use the third result!
c = t[2]
So errors
is a list that contains items that are tuples of length 2 or 3. You want a way to unpack tuples of varying length in a for-loop. As you have noted, there is no clean way to do this in Python2. Rather than coming up with a clever way of implementing this behavior, I would suggest making sure that your errors list always contains tuples of length of 3. This can be done every time you add an item to errors
, or after the fact, like this:
errors = [(x[0], x[1], x[2]) if len(x) == 3 else (x[0], x[1], None) for x in errors]
Or you could make a generator (which goes against my advice of not finding clever way to implement this behavior):
def widen_tuples(iter, width, default=None):
for item in iter:
if len(item) < width:
item = list(item)
while len(item) < width:
item.append(default)
item = tuple(item)
yield item
Use it like this:
>>> errors = [(1, 2), (1, 2, 3)]
>>> for a, b, c in widen_tuples(errors, 3):
... print a, b, c
1 2 None
1 2 3
You could write a utility function to make your results uniform:
def do_something2():
return 1, 2
def do_something3():
return 1, 2, 3
def do_something5():
return 1, 2, 3, 4, 5
def uniform_result(*args):
return args[0], args[1], args[2:]
a, b, c = uniform_result(*do_something2())
print a, b, c
# 1 2 ()
a, b, c = uniform_result(*do_something3())
print a, b, c
# 1 2 (3,)
a, b, c = uniform_result(*do_something5())
print a, b, c
# 1 2 (3, 4, 5)
I suggest complementing the list to the necessary length with the None
elements:
data = give_me_list()
(val1, val2, val3) = data + (3 - len(data)) * [None]
3 is the number of the left hand side values. If the list can have excessive elements, then use protection against that:
data = give_me_list()[:3]
(val1, val2, val3) = data + (3 - len(data)) * [None]
精彩评论