Random thoughts shooting out of volatile mind
Conditional "import" in Python
Normally in Python when we try to import a module and module doesn't exist the interpreter will throw  ImportError, this is a normal behavior . But in some cases like when Python version changes some functions are moved from one module to other and sometime the module names itself are changed. For eg. in Python 2.6 we have urllib urllib2 modules but in Py3k these modules are combined and all request response related functions are present in urllib.request and all errors are unders urrlib.error module. Functions like urlencode quote unquote which were in urllib module in Python2.6 are under urllib.request Py3k. This case of moving from Python 2.x to Py3k can be easily done by tool called 2to3.But lets say moving from Python2.5 to Python2.6 how do we handle this situation?. Well below is the solution (applicable when modules are renamed or moved during version change)

Problem: When I started working on SILPA I was running Debian Squeeze which had Python 2.5 as system default Python, but recently Debian Squeeze transitioned to Python 2.6 as default Python. We had some issue in the URL routing logic of the SILPA which I fixed 2 days back for which I used a function called parse_qs from urlparse module and everything worked fine on my system. I pushed the changes to the main git repository. Now the problem begins 2 mirrors of SILPA have Cron job setup to periodically pull the changes from git, and next day it was reported that 2 of the mirrors where throwing 500 internal server error. And its time for me to find what was causing the issue :).

Reason: Mirror instance of the SILPA were running older version of Python.(2.5) and the function parse_qs was not defined in the module urlparse which was causing the ImportError.

Solution: I figured out that in Python 2.5 version parse_qs is present but in cgi module instead of urlparse. So to make the code work in both Python versions (i.e. 2.5 and 2.6) I need to do a conditional import as shown below

try:
    from urlparse import parse_qs
except ImportError:
    # Fall back for Python 2.5
    from cgi import parse_qs

So I want to import parse_qs from urlparse module and if interpreter throws ImportError it means the Python version is <2.6 so import the function from cgi module instead. So code is now backward compatible with Python2.5. Well that's it I call this as conditional importing I don't know what is the exact name for this method :). If you have any suggestions please do comment.

-- Vasudev
Posted by: copyninja on Saturday, 4 December 2010

blog comments powered by Disqus
Fork me on GitHub