TL;DR: Add a comma to this line in keydb.py to make a tuple out of the arg to execute.
Context: I'm setting up a new testclearinghouse, and try to use up-to-date versions of software packages mentioned on the CH installation docs. This means Python 2.7, MariaDB (to replace MySQL), Django 1.6.11(last 1.6 release), etc.
Node accounting and setting up vessels didn't work. The logs show many instances of TypeErrors, noting that not all arguments converted during string formatting in common/api/keydb.py, line 98
The problem there is subtle, and only shows in interplay with the current MySQLdb bindings. The call appears on first glance to use plain old C printf-style string formatting, so you would expect the %s be replaced by the contents of the next argument of this call. Funnily enough, this isn't how Pythonic string formatting works (which would be '%s' % variable, note the percent sign after the quote); however, previous versions of MySQLdb contained code that would make the execute function take arguments (and thus do the C-style thing) correctly, or at least correct enough for our code to work.
The new bindings still kept the C-style interface, but the code to handle the argument changed to treat differently dict args and args of any other type. For the former, it would loop over keys and values; for the latter, it just loops over the arg. What they expect non-dict types to be is essentially tuple or list:
# This does what you would expect
for element in tuple_or_list:
do_something_with(element)
In the case of our code, the argument isn't a tuple though --- it's a string, wrapped in parentheses. Tuples with one element need a trailing comma after the element! So what the expansion code in MySQLdb does is
# This is not what is meant!
for single_character in string_arg:
do_something_with(single_character)
So the updated MySQLdb bindings substitute %s in the query with just the first char of the string. The other chars can't be converted by the format command, resulting in the error. That was a fun one to catch!
Example full traceback from log:
[2015-07-21 12:58:15.827022] DEBUG 782032177 Exception from SetVesselOwner (module __main__): <type 'exceptions.TypeError'> not all arguments converted during string formatting
[2015-07-21 12:58:15.827139] CRITICAL 782032177 The backend had an internal error: Traceback (most recent call last):
File "/home/ch/deployment/clearinghouse/backend/backend_daemon.py", line 157, in _dispatch
File "/home/ch/deployment/clearinghouse/common/util/decorators.py", line 234, in do_logging_func_call
File "/home/ch/deployment/clearinghouse/backend/backend_daemon.py", line 267, in SetVesselOwner
File "/home/ch/deployment/clearinghouse/backend/backend_daemon.py", line 90, in _get_node_handle_from_nodeid
File "/home/ch/deployment/clearinghouse/common/api/keydb.py", line 98, in get_private_key
File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 187, in execute
TypeError: not all arguments converted during string formatting
TL;DR: Add a comma to this line in
keydb.pyto make a tuple out of the arg toexecute.Context: I'm setting up a new testclearinghouse, and try to use up-to-date versions of software packages mentioned on the CH installation docs. This means Python 2.7, MariaDB (to replace MySQL), Django 1.6.11(last 1.6 release), etc.
Node accounting and setting up vessels didn't work. The logs show many instances of
TypeErrors, noting thatnot all arguments converted during string formattingincommon/api/keydb.py, line 98The problem there is subtle, and only shows in interplay with the current MySQLdb bindings. The call appears on first glance to use plain old C
printf-style string formatting, so you would expect the%sbe replaced by the contents of the next argument of this call. Funnily enough, this isn't how Pythonic string formatting works (which would be'%s' % variable, note the percent sign after the quote); however, previous versions ofMySQLdbcontained code that would make theexecutefunction take arguments (and thus do the C-style thing) correctly, or at least correct enough for our code to work.The new bindings still kept the C-style interface, but the code to handle the argument changed to treat differently
dictargs and args of any other type. For the former, it would loop over keys and values; for the latter, it just loops over the arg. What they expect non-dicttypes to be is essentiallytupleorlist:In the case of our code, the argument isn't a
tuplethough --- it's a string, wrapped in parentheses. Tuples with one element need a trailing comma after the element! So what the expansion code in MySQLdb does isSo the updated MySQLdb bindings substitute
%sin the query with just the first char of the string. The other chars can't be converted by the format command, resulting in the error. That was a fun one to catch!Example full traceback from log: