From 5854a68af87e7bfcc33e5e8228a602a0aad51014 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Tue, 13 Sep 2011 16:59:46 -0400 Subject: [PATCH 1/2] ENH: add package_check and skip_if_no_package to ease conditional testing --- pandas/util/testing.py | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/pandas/util/testing.py b/pandas/util/testing.py index db314f6eb7cd2..c70aa3b1b8cff 100644 --- a/pandas/util/testing.py +++ b/pandas/util/testing.py @@ -5,6 +5,8 @@ import string import sys +from distutils.version import LooseVersion + from numpy.random import randn import numpy as np @@ -216,3 +218,66 @@ def makeLongPanel(): return wp.to_long() +# Dependency checks. Copied this from Nipy/Nipype (Copyright of +# respective developers, license: BSD-3) +def package_check(pkg_name, version=None, app='pandas', checker=LooseVersion, + exc_failed_import=ImportError, + exc_failed_check=RuntimeError): + """Check that the minimal version of the required package is installed. + + Parameters + ---------- + pkg_name : string + Name of the required package. + version : string, optional + Minimal version number for required package. + app : string, optional + Application that is performing the check. For instance, the + name of the tutorial being executed that depends on specific + packages. + checker : object, optional + The class that will perform the version checking. Default is + distutils.version.LooseVersion. + exc_failed_import : Exception, optional + Class of the exception to be thrown if import failed. + exc_failed_check : Exception, optional + Class of the exception to be thrown if version check failed. + + Examples + -------- + package_check('numpy', '1.3') + package_check('networkx', '1.0', 'tutorial1') + + """ + + if app: + msg = '%s requires %s' % (app, pkg_name) + else: + msg = 'module requires %s' % pkg_name + if version: + msg += ' with version >= %s' % (version,) + try: + mod = __import__(pkg_name) + except ImportError: + raise exc_failed_import(msg) + if not version: + return + try: + have_version = mod.__version__ + except AttributeError: + raise exc_failed_check('Cannot find version for %s' % pkg_name) + if checker(have_version) < checker(version): + raise exc_failed_check(msg) + +def skip_if_no_package(*args, **kwargs): + """Raise SkipTest if package_check fails + + Parameters + ---------- + *args Positional parameters passed to `package_check` + *kwargs Keyword parameters passed to `package_check` + """ + from nose import SkipTest + package_check(exc_failed_import=SkipTest, + exc_failed_check=SkipTest, + *args, **kwargs) From 960a5037942569ccf316d97dd40c898598bde172 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Tue, 13 Sep 2011 17:00:19 -0400 Subject: [PATCH 2/2] ENH: make blosc-dependent tests skip if pytables < 2.2 --- pandas/io/tests/test_pytables.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/pandas/io/tests/test_pytables.py b/pandas/io/tests/test_pytables.py index fb809956c3210..be3faff37eb41 100644 --- a/pandas/io/tests/test_pytables.py +++ b/pandas/io/tests/test_pytables.py @@ -15,6 +15,11 @@ except ImportError: raise nose.SkipTest('no pytables') +from distutils.version import LooseVersion + +_default_compressor = LooseVersion(tables.__version__) >= '2.2' \ + and 'blosc' or 'zlib' + class TesttHDFStore(unittest.TestCase): path = '__test__.h5' scratchpath = '__scratch__.h5' @@ -82,16 +87,25 @@ def test_put(self): def test_put_compression(self): df = tm.makeTimeDataFrame() - self.store.put('c', df, table=True, compression='blosc') - tm.assert_frame_equal(self.store['c'], df) self.store.put('c', df, table=True, compression='zlib') tm.assert_frame_equal(self.store['c'], df) + # can't compress if table=False + self.assertRaises(ValueError, self.store.put, 'b', df, + table=False, compression='zlib') + + def test_put_compression_blosc(self): + tm.skip_if_no_package('tables', '2.2', app='blosc support') + df = tm.makeTimeDataFrame() + # can't compress if table=False self.assertRaises(ValueError, self.store.put, 'b', df, table=False, compression='blosc') + self.store.put('c', df, table=True, compression='blosc') + tm.assert_frame_equal(self.store['c'], df) + def test_put_integer(self): # non-date, non-string index df = DataFrame(np.random.randn(50, 100)) @@ -346,7 +360,7 @@ def test_select_filter_corner(self): def _check_roundtrip(self, obj, comparator, compression=False): options = {} if compression: - options['complib'] = 'blosc' + options['complib'] = _default_compressor store = HDFStore(self.scratchpath, 'w', **options) try: @@ -360,7 +374,7 @@ def _check_roundtrip(self, obj, comparator, compression=False): def _check_roundtrip_table(self, obj, comparator, compression=False): options = {} if compression: - options['complib'] = 'blosc' + options['complib'] = _default_compressor store = HDFStore(self.scratchpath, 'w', **options) try: