[Biopython-dev] External python dependencies and doctests

Peter biopython at maubp.freeserve.co.uk
Sat Feb 14 18:47:30 UTC 2009

Hi all,

Currently the doctest handling in run_tests.py requires some special
cases for those modules with an optional external dependency, for
example the Bio.Statistics.lowess doctests will only work if NumPy is
installed.  We *could* just run all the doctests, and catch and ignore
any import errors.  However, an import error might be a real error in
Biopython (e.g. if something was deleted or moved).  This is therefore
probably a bad idea.

I was thinking we could introduce new exception(s) which subclasses
both the ImportError and our MissingExternalDependencyError exception.
 This can then be treated as another variant of
MissingExternalDependencyError and ignored by run_tests.py, plus as it
is also an ImportError any third party scripts can continue to catch
import errors as before.

This means that run_tests.py doesn't need to know if some doctests
require NumPy (or ReportLab) or not - we can just run them and find
out (see patch below).  The downside is that any bits of Biopython
where we import numpy or reportlab (or at least those with doctests)
would need to catch any import error and re-raise it (as below).

I'm not sure if this is a good idea or not.  It would certainly be
useful if we want to switch to having the doctests found automatically
(which is probably a good idea in the long run - the hand coded list
was just my short term pragmatic solution).


Index: Bio/__init__.py
RCS file: /home/repository/biopython/biopython/Bio/__init__.py,v
retrieving revision 1.31
diff -r1.31 __init__.py
> class MissingPythonDependencyError(MissingExternalDependencyError,ImportError) :
>     """Exception for missing python libraries.
>     This should be used when "import numpy" or "import reportlab" fail.
>     This exception subclasses both the standard python ImportError, and
>     our Biopython MissingExternalDependencyError meaning it can be caught
>     using "except ImportError" or "except MissingExternalDependencyError".
>     This is important for our test framework.
>     """
>     pass
> class MissingNumPyDependencyError(MissingPythonDependencyError) :
>     """Exception for when NumPy is not installed."""
>     def __str__(self) :
>         return "This requires the Numerical Python library, NumPy, " + \
>                "freely available from http://www.numpy.org"
> class MissingReportLabDependencyError(MissingPythonDependencyError) :
>     """Exception for when ReportLab is not installed."""
>     def __str__(self) :
>         return "This requires the python library ReportLab, " + \
>                "freely available from http://www.reportlab.org"
Index: Bio/Statistics/lowess.py
RCS file: /home/repository/biopython/biopython/Bio/Statistics/lowess.py,v
retrieving revision 1.10
diff -r1.10 lowess.py
< import numpy
> try :
>     import numpy
> except ImportError:
>     from Bio import MissingNumPyDependencyError
>     raise MissingNumPyDependencyError()
Index: Bio/Cluster/__init__.py
RCS file: /home/repository/biopython/biopython/Bio/Cluster/__init__.py,v
retrieving revision 1.13
diff -r1.13 __init__.py
< import numpy
> try :
>     import numpy
> except ImportError:
>     from Bio import MissingNumPyDependencyError
>     raise MissingNumPyDependencyError()
Index: Bio/Graphics/__init__.py
RCS file: /home/repository/biopython/biopython/Bio/Graphics/__init__.py,v
retrieving revision 1.2
diff -r1.2 __init__.py
<     raise ImportError("Install ReportLab if you want to use
Bio.Graphics. You can find ReportLab at
>     from Bio import MissingReportLabDependencyError
>     raise MissingReportLabDependencyError()

More information about the Biopython-dev mailing list