Python Programming, news on the Voidspace Python Projects and all things techie.

A Little Bit of Python: Episodes 7 and 8

Two more episodes of A Little Bit of Python have been posted. A Little Bit of Python is an occasional podcast on Python related topics with myself, Brett Cannon, Jesse Noller, Steve Holden and Andrew Kuchling.

A little bit of Python is now listed on iTunes!

A Little Bit of Python on iTunes (Opens in iTunes and a web page)

Episode 7 is a discussion of Unladen Swallow, a branch of CPython that uses the LLVM (Low Level Virtual Machine) to provide a JIT (Just-In-Time compiler) for performance improvements in Python. This episode was recorded before PyCon. Since then a couple of decisions about Unladen Swallow have been made, that were still open questions when we recorded this episode:

PEP 3146 has been tentatively accepted. With the proviso that it depends on startup time improvements, memory use reductions and further performance improvements (all discussed in the PEP), Unladen Swallow has been approved to merge with CPython. A new subversion branch, py3k-jit has been created for this purpose.

The version of Python that the merge targets is Python 3.3. As Python 3.2 will be out later this year it is realistically going to be about 2 years before Python with an Unladen Swallow JIT is released. This is plenty of time for the outstanding issues to be addressed and for users to test Unladen Swallow.

Episode 8 is an interview with Mark Shuttleworth recorded by Steve Holden at PyCon.

General links for the podcast feeds and a webpage with an embedded flash player:

If you have feedback, insults or suggestions for new topics you can email us on: all@bitofpython.com.

We have a twitter account, so for news on new episodes follow @bitofpython. A Little Bit of Python is also syndicated on Hacker Public Radio (although they're only up to episode two so far).

Exception Handling Code for Python 2 and 3

The right way to maintain a library for both Python 2 and 3 is to run your tests with Python 2.6 with Python 3 warnings switched on. This doesn't mean that you have to make Python 2.6 your minimum supported version of Python, but it will warn you where you are doing things that either won't work or will have different behaviour in Python 3. For example:

$ python -3 Python 2.6.4 (r264:75821M, Oct 27 2009, 19:48:32) [GCC 4.0.1 (Apple Inc. build 5493)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> 1 > 'a' __main__:1: DeprecationWarning: comparing unequal types not supported in 3.x False >>>

Once you have done this you can use 2to3 to convert your codebase. Run your tests again and find any problems. The idea is to fix them in your Python 2 codebase (possibly resorting to compatibility layers with separate libraries for things like string / bytes IO) so that 2to3 is fully able to produce a working Python 3 version of your code. Using distribute you can even have 2to3 run automatically when your package is installed on Python 3.

That is the right way. For smaller modules it is possible, but sometimes not fun, to keep a single codebase that runs fine with both Python 2 and Python 3. The one module I maintain like this is discover, a backport of the new unittest test discovery . There are various tricks to getting around the slightly different syntax and semantics between Python 2 and Python 3. One of these is handling exceptions.

For Python 2.5 and earlier you define your try..except blocks thusly:

try : do_something () except AttributeError , e : handle_this ( e ) except TypeError , e : handle_that ( e ) else : finish ()

For Python 3, and also Python 2.6 if you don't mind being incompatible with earlier versions of Python, you do:

try : do_something () except AttributeError as e : handle_this ( e ) except TypeError as e : handle_that ( e ) else : finish ()

So you can't write exception handling code that will work with both Python 2.5 and 3.X using these constructs. Instead you can use the following nasty trick:

import sys try : do_something () except : ExceptionClass , e = sys . exc_info ()[: 2 ] if ExceptionClass is AttributeError : handle_this ( e ) elif ExceptionClass is TypeError : handle_that ( e ) else : raise else : finish ()

Not very pretty, and don't forget to fix it as soon as you drop support for Python 2.5, but it works fine.

Archives