Stop writing Python 3.5 incompatible code :-)

Frank Millman frank at chagford.com
Thu Jan 14 01:27:25 EST 2016


This is a tongue-in-cheek follow-up to the thread on Python 4 incompatible 
code, but it did happen to me, and may help someone else.

I execute a lot of database SELECT commands. In many cases I expect to get 
only one row returned, but it could be zero or more than one.

Using LBYL, one would retrieve the row(s) and check the length. I found a 
way to use EAFP, as follows -

cur.execute('SELECT ...')
(row,) = cur

This uses tuple unpacking, and only works if exactly one row is returned. If 
it fails it raises ValueError, but I need to know whether it failed because 
no rows were returned, or more than one row was returned. The only way I 
could figure out how to achieve this was to parse the error message.

If 0 rows were returned, the message is 'need more than 0 values to unpack'.

If > 1 rows were returned, the message is 'too many values to unpack'.

So my test was -

except ValueError as e:
    if str(e).startswith('need'):
        # 0 rows returned
    else:
        # > 1 rows returned

This has worked for years, but with 3.5 it stopped working. It took me a 
while to figure out why. Lo and behold, the error message has changed! Now, 
if 0 rows are returned, the message is 'not enough values to unpack'.

Luckily the other message has not changed, so now my test is -

except ValueError as e:
    if str(e).startswith('too many'):
        # > 1 rows returned
    else:
        # 0 rows returned

Now it works with both versions.

Frank Millman





More information about the Python-list mailing list