Python Style Tip: Drop in Types

Posted on September 23, 2009

I recently came upon an issue whilst working on a project written in Python that was kind of interesting. After having nearly completed an API to a third-party service, I discovered that their system was sensitive to the order in which the fields appeared. They had given us some API code in Perl and PHP, but no message format specification. So I threw up a small Python web server that would just capture all of the POST data sent to any URL and fired all the example API code I had. From there I went about creating a Pythonic API that I would be happy using and used the captured messages as my target. I decided dictionaries were going to be my primary data-structure since they mapped well to the message format I would have to serialize to. I went on my way and implemented the most simple solution possible and within an afternoon had it all ready to go. And when I started pointing my new Python API code at the test servers provided by this third-party service I kept getting the wrong responses.

Once I had narrowed down the problem to the field ordering issue, it became apparent that Python’s built-in dictionaries were not going to cut it. The update method of the standard dictionary object does not guarantee the order of the items added, ruining the order of the fields as I serialized them. Normally the serialization format should be agnostic to field order, but this is a situation where practicality beats purity. I did a quick search and found an ordered dictionary implementation in Python within a few minutes. Then I realized that I wasn’t going to just be able to import it and re-run my tests. Throughout my code I had assigned “bare” dictionaries…

It wasn’t too hard to run a couple of regular expressions to replace all those assignments with explicit “dict” objects, but if I had used it in the first place I would’ve saved some time. Here’s what I mean:

def my_method(arg1, arg2, arg3):
    a_dict = {'my_long_name_1': arg1,
              'my_longer_name_2': arg2,
              'my_pretty_long_name': arg3}
    req_str = dict_to_message(a_dict)
    response = server.do_request(req_str)
    return response

However, I had a lot of methods that looked like this. Mainly because I didn’t want to just use kwargs for the sake of being terse. This was an API after-all and it should be easy to identify what each parameter is and what its for (in theory). But when I found that plain dictionaries weren’t going to work out, I couldn’t just add an import line to the module and go. However, from now on if I’m creating dictionaries in my code I think I might prefer using “dict” directly rather than relying on the syntax. Here’s why:

from odict import OrderedDict as dict

def my_method(arg1, arg2, arg3):
    a_dict = dict(my_long_name_1=arg1,
                  my_longer_name_2=arg2,
                  my_pretty_long_name=arg3)
    req_str = dict_to_message(a_dict)
    response = server.do_request(req_str)
    return response

And this way if I find that my initial design isn’t sufficient, I’d just have to change the import line to change the data type. It’s a small thing, but it should save me some editing time. Any thoughts or suggestions are welcome of course.