Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working around Python bug in different versions

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?

like image 570
Danger Mouse Avatar asked Sep 08 '10 18:09

Danger Mouse


People also ask

Can you have multiple versions of Python installed?

If you wish to use multiple versions of Python on a single machine, then pyenv is a commonly used tool to install and switch between versions. This is not to be confused with the previously mentioned depreciated pyvenv script. It does not come bundled with Python and must be installed separately.

How do I manage multiple Python versions in Ubuntu?

Install that version using "make install". Install all other versions using "make altinstall". For example, if you want to install Python 2.5, 2.6 and 3.0 with 2.6 being the primary version, you would execute "make install" in your 2.6 build directory and "make altinstall" in the others.


2 Answers

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.

like image 152
Scott Griffiths Avatar answered Sep 28 '22 04:09

Scott Griffiths


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.

like image 33
Ned Batchelder Avatar answered Sep 28 '22 02:09

Ned Batchelder