Stop helping me python!

/media/images/snake_with_hat.jpg

I recently added a new django app to the site and took the opportunity to finally sync this code with the code that was actually running on my SBC webserver. The new code seemed to be solid but I'd made some radical changes and I wasn't confident I didn't break things. Of course this just meant the longer I delayed the more the two code bases diverged.

Of course there was an issue. It came up when I wanted to add an image to a blog entry and it crashed because I'd neglected to update the blog model to work with the new thumbnail API.

This started a frantic scramble to fix it within my development framework, a rootless podman container, but I learned that had issues too. Group permissions weren't getting propagated into the container so I didn't have write access to the database.

After some investigation I found the issue and fixed it without any way of testing it before pushing it to 'production' (by which I mean the SBC that runs this site - which no one reads). It crashed and so I was forced to temporarily turn on debug to see why.

Python was complaining that my code was trying to index a tuple with a string. This was baffling because my code wasn't working with tuples. Eventually I tracked the fault down to this block of code:

mediadict = {'type': 'image',
             'thumbfilepath': Path(thumbfilepath),
             'filepath': Path(newpath),
             'cstring': 'center-block',
             'constraint': 'width max',
             'filesize': image_filesize,
             'filelength': 'unknown'},
if self.resize:
    mediadict['constraint'] = str(self.resize)

im = thumbnail.make_thumbnail(mediadict)

Spot the issue? Here it is in an interpreter:

[ins] In [1]: t = {'a':1, 'b':2}

[ins] In [2]: t
Out[2]: {'a': 1, 'b': 2}

[ins] In [3]: t = {'a':1, 'b':2},

[ins] In [4]: t
Out[4]: ({'a': 1, 'b': 2},)

I accidentally left a trailing comma on my dictionary instantiation so python automatically enclosed it in a tuple!

This is both surprising and horrifying. It should raise an error or, if you want to be syntactically permissive, ignore the comma altogether. I cannot imagine anyone expecting a trailing comma to automatically convert your object into a different (and unmentioned) data structure.

In fact this bug is so alarming I'm beginning to think it may be time to start edging away from the language altogether. Python is convenient for making something fast but it may be too friendly.

You can see the changes I made here.