views:

95

answers:

2

I've come across a bug in Python (at least in 2.6.1) for the bytearray.fromhex function. This is what happens if you try the example from the docstring:

>>> bytearray.fromhex('B9 01EF')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: fromhex() argument 1 must be unicode, not str

This example works fine in Python 2.7, and I want to know the best way of coding around the problem. I don't want to always convert to unicode as it's a performance hit, and testing which Python version is being used feels wrong.

So is there a better way to code around this sort of problem so that it will work for all versions, preferably without slowing it down for the working Pythons?

+6  A: 

For cases like this it's good to remember that a try block is very cheap if no exception is thrown. So I'd use:

try:
    x = bytearray.fromhex(some_str)
except TypeError:
    # Work-around for Python 2.6 bug 
    x = bytearray.fromhex(unicode(some_str))

This lets Python 2.6 work with a small performance hit, but 2.7 shouldn't suffer at all. It's certainly preferable to checking Python version explicitly!

The bug itself (and it certainly does seem to be one) is still present in Python 2.6.5, but I couldn't find any mention of it at bugs.python.org, so maybe it was fixed by accident in 2.7! It looks like a back-ported Python 3 feature that wasn't tested properly in 2.6.

Scott Griffiths
+3  A: 

You can also create your own function to do the work, conditionalized on what you need:

def my_fromhex(s):
    return bytearray.fromhex(s)

try:
    my_fromhex('hello')
except TypeError:
    def my_fromhex(s):
        return bytearray.fromhex(unicode(s))

and then use my_fromhex in your code. This way, the exception only happens once, and during your runtime, the correct function is used without excess unicode casting or exception machinery.

Ned Batchelder