After debugging a funny problem in tests which came from Circular Imports that got eaten, let me show you how you can test, if some package is available, and how you can test, if that package is new enough:
So, this is a common snippet:
try: import Products.LinguaPlone except ImportError: HAS_LINGUA_PLONE = False else: HAS_LINGUA_PLONE = True
That might trigger circular import exceptions. It will not always fail, depending on what gets imported first. The circular import gets caught by the "except ImportError:" line. So you will not see an exception here, but in some other funny place. Good luck debugging that.
Another thing that I see sometimes is a check to implement backward compatibility
try: from foo import new_thing except ImportError: OLD_FOO = True else: OLD_FOO = False if OLD_FOO: def new_thing(something): return something + 'cool'
This can sometimes trigger ImportErrors and it does not show its intention like it could.
pkg_resources has an API which can help you to clarify things:
import pkg_resources try: pkg_resources.get_distribution('Products.LinguaPlone>=4.0.0') except pkg_resources.DistributionNotFound: HAS_LINGUA_PLONE = False HAS_CURRENT_LINGUA_PLONE = False except pkg_resources.VersionConflict: HAS_LINGUA_PLONE = True HAS_CURRENT_LINGUA_PLONE = False else: HAS_LINGUA_PLONE = True HAS_CURRENT_LINGUA_PLONE = True `
Now, that is a bit more verbose, but