Wednesday, March 3, 2010

Include version information in your Python packages

Quite some time ago, I wrote a list of what to do and what not to do when creating a Python package. In the spirit of that post, I have another do item:

Do include version information somewhere in your package. When I say package here, I'm referring to the Python concept - the thing which can be imported and manipulated programmatically. Here is a random assortment of real-life examples of what I mean:

>>> import sys
>>> sys.version
'2.6.4 (r264:75706, Dec  7 2009, 18:45:15) \n[GCC 4.4.1]'
>>> import OpenSSL
>>> OpenSSL.__version__
'0.10'
>>> import gmpy
>>> gmpy.version()
'1.04'
>>> import gtk
>>> gtk.gtk_version
(2, 18, 3)
>>> gtk.pygtk_version
(2, 16, 0)
>>> import pyasn1
>>> pyasn1.majorVersionId
'1'
>>> import win32api
>>> win32api.GetFileVersionInfo(win32api.__file__, chr(92))['FileVersionLS'] >> 16
212

You can see several conventions represented here. Some of them are better than others (in case you need a hint, gtk is doing something pretty nice; win32api is towards the other end of the spectrum). However, even the worst of these is providing the desired information. Compare this to:

>>> import zope.interface
>>> [x for x in dir(zope.interface) if 'version' in x]
[]
>>> import subunit
>>> [x for x in dir(subunit) if 'version' in x]
[]

This is a simple piece of information, and after you've actually picked a version of something and installed it, it's hardly ever of much interest. However, when it is of interest, you really want to be able to get it. You don't want to rely on the memory of some user about which version they installed when you're tracking down some poor interaction.

So. Do you maintain a Python package? Does it expose its version somehow? If not, fix it!