Nasty little bug

- Image via Wikipedia
So i gut pulled the updates for pydra, did some hacking and decided to change a setting in the web interface. There was a ugly surprise waiting for me there :/:
{% if form.fields %}
{% regroup form by module_name as modules %}
{% for module in modules %}
Off course, like any real (wo)man would do as soon as i spotted the red line (context? bah!) i went to view to check what is being passed to the template. Uh, oh, modules ain't passed at all? Time for heavy machinery. Did some toying with it but still no luck, maybe i should after all read the error?
My journey continues in the django docs figuring out what the hell is the regroup tag :-). Hrm, the regroup tag takes as input form, so there must be something wrong with it? After trying to see the connection between the error and the code i kinda gave up and resorted to the debugger again. The natural thing to do is to have a closer look at the object. I tend to do that with the pprint.pprint function and it looks ok. Let's just for the sake of it try to simple print it?
ValueError: 'need more than 1 value to unpack'
Surprise surprise! Let's step into the django internals. Not surprisingly this took me to django's string conversion code and finally to forms.py. The problem?
--> 165 output.append(normal_row % {'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': unicode(bf), 'help_text':
help_text})
166 if top_errors:
ipdb>
After having a look at the values in the dict it turns out you can't print the bf variable. Hrm, ok, next step? The use of debug statement in pdb to enter the wonderful world of spawning the recursive python debugger! So after quite a bit of fiddling in there i found out that my instance is ChoiceField, but i'm not creating any Choicefields?!?!?
if setting.choices:
field = forms.ChoiceField(choices=setting.choices, **kwargs)
else:
field = setting.field(**kwargs)
As it turns out the dbsettings is deciding that it can be smarter than the programmer using it. Here it sets the field to the ChoiceField regardless of what you told it to be. It is ignoring one of pythons core principles, explicit is better than implicit. What triggered this code?
#how it is defined
def __init__(self, description=None, help_text=None, choices=None, default=None):
...
#how it is used
tasks_dir = dbsettings.StringValue('tasks_dir', 'tasks directory','Directory where tasks are stored. Absolute paths are prefered.', default='./pydra_server/task_cache')
As you can see here, description parameter is assigned 'tasks_dir', help_text get's 'tasks directory' and choices get's 'Directory where tasks are stored. Absolute paths are prefered.'. The fix?
tasks_dir = dbsettings.StringValue('tasks_dir', 'Directory where tasks are stored. Absolute paths are prefered.', default='./pydra_server/task_cache')
And yes i wasted shitload of time to change the single line of code.
![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_e.png?x-id=efbd31ea-a534-44b6-ac72-f22413890aa9)