A reminder: string concatenation really is string concatenation

November 11, 2012

Once upon a time when I was starting to write Python, I scribbled down the following code:

def warn(s):
  sys.stderr.write(sys.argv[0] + ": " + s + "\n")

(More or less. My actual code had an error and so didn't even work.)

Many Python programmers are wincing, because of course string concatenation is both somewhat inefficient and not the idiomatic way to do this; you should be using % string formatting. But there's another somewhat more subtle reason to avoid code like this, one that I ran into recently when I stumbled over this code the hard way by having it blow up in my face.

The surrounding code went something like this:

try:
  o, r = getopt.getopt(....)
except getopt.error, cause:
  warn(cause)
  ....

This failed. You see, the subtle problem with string concatenation is that it really is string concatenation. Unlike % formatting, it will not try to str() objects to convert them to strings; if they are not strings already, it just fails. It is of course easy to overlook this if you usually give your code actual strings; passing in a non-string object that can be stringified may be an uncommon corner case that you don't test explicitly.

This code actually exposes an interesting effect of Python's slow changes between Python 1.x and Python 2. Back in the old days exceptions actually were strings instead of objects that can be string-ified, and so this code could work when fed one of those exceptions. I wrote the program this code appears in back in 2003 or earlier and I believe we were still using Python 1.5 at the time (although it wasn't the current version even then); the 1.5.2 version of the getopt module appears to still have been using string exceptions at the time. So this might have been less crazy back then than it appears now (although it was still the wrong way to do it plus my actual implementation had a bug).

Written on 11 November 2012.
« Why Unix doesn't have user-changeable namespaces
Explaining an RPM oddity »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Nov 11 01:56:48 2012
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.