diff --git a/pandas/tests/io/sas/test_sas7bdat.py b/pandas/tests/io/sas/test_sas7bdat.py index c059f01ecf3f4..5da347e47957c 100644 --- a/pandas/tests/io/sas/test_sas7bdat.py +++ b/pandas/tests/io/sas/test_sas7bdat.py @@ -1,6 +1,7 @@ import pandas as pd from pandas.compat import PY2 import pandas.util.testing as tm +import pandas.util._test_decorators as td from pandas.errors import EmptyDataError import os import io @@ -71,8 +72,8 @@ def test_from_iterator(self): tm.assert_frame_equal(df, df0.iloc[2:5, :]) rdr.close() + @td.skip_if_no('pathlib') def test_path_pathlib(self): - tm._skip_if_no_pathlib() from pathlib import Path for j in 0, 1: df0 = self.data[j] @@ -82,8 +83,8 @@ def test_path_pathlib(self): df = pd.read_sas(fname, encoding='utf-8') tm.assert_frame_equal(df, df0) + @td.skip_if_no('py.path') def test_path_localpath(self): - tm._skip_if_no_localpath() from py.path import local as LocalPath for j in 0, 1: df0 = self.data[j] diff --git a/pandas/tests/io/test_common.py b/pandas/tests/io/test_common.py index 707580bfe9601..13a393d9109ae 100644 --- a/pandas/tests/io/test_common.py +++ b/pandas/tests/io/test_common.py @@ -8,6 +8,7 @@ import pandas as pd import pandas.util.testing as tm +import pandas.util._test_decorators as td from pandas.io import common from pandas.compat import is_platform_windows, StringIO, FileNotFoundError @@ -67,17 +68,15 @@ def test_expand_user_normal_path(self): assert expanded_name == filename assert os.path.expanduser(filename) == expanded_name + @td.skip_if_no('pathlib') def test_stringify_path_pathlib(self): - tm._skip_if_no_pathlib() - rel_path = common._stringify_path(Path('.')) assert rel_path == '.' redundant_path = common._stringify_path(Path('foo//bar')) assert redundant_path == os.path.join('foo', 'bar') + @td.skip_if_no('py.path') def test_stringify_path_localpath(self): - tm._skip_if_no_localpath() - path = os.path.join('foo', 'bar') abs_path = os.path.abspath(path) lpath = LocalPath(path) diff --git a/pandas/tests/io/test_excel.py b/pandas/tests/io/test_excel.py index 4efeeecf8ee4a..274d60c40e83f 100644 --- a/pandas/tests/io/test_excel.py +++ b/pandas/tests/io/test_excel.py @@ -13,6 +13,7 @@ import pandas as pd import pandas.util.testing as tm +import pandas.util._test_decorators as td from pandas import DataFrame, Index, MultiIndex from pandas.compat import u, range, map, BytesIO, iteritems from pandas.core.config import set_option, get_option @@ -650,11 +651,10 @@ def test_read_from_file_url(self): tm.assert_frame_equal(url_table, local_table) + @td.skip_if_no('pathlib') def test_read_from_pathlib_path(self): # GH12655 - tm._skip_if_no_pathlib() - from pathlib import Path str_path = os.path.join(self.dirpath, 'test1' + self.ext) @@ -665,11 +665,10 @@ def test_read_from_pathlib_path(self): tm.assert_frame_equal(expected, actual) + @td.skip_if_no('py.path') def test_read_from_py_localpath(self): # GH12655 - tm._skip_if_no_localpath() - from py.path import local as LocalPath str_path = os.path.join(self.dirpath, 'test1' + self.ext) diff --git a/pandas/tests/io/test_pytables.py b/pandas/tests/io/test_pytables.py index 6df31b73da9b7..d63764e90d26e 100644 --- a/pandas/tests/io/test_pytables.py +++ b/pandas/tests/io/test_pytables.py @@ -5119,11 +5119,10 @@ def test_read_nokey_empty(self): store.close() pytest.raises(ValueError, read_hdf, path) + @td.skip_if_no('pathlib') def test_read_from_pathlib_path(self): # GH11773 - tm._skip_if_no_pathlib() - from pathlib import Path expected = DataFrame(np.random.rand(4, 5), @@ -5137,11 +5136,10 @@ def test_read_from_pathlib_path(self): tm.assert_frame_equal(expected, actual) + @td.skip_if_no('py.path') def test_read_from_py_localpath(self): # GH11773 - tm._skip_if_no_localpath() - from py.path import local as LocalPath expected = DataFrame(np.random.rand(4, 5), diff --git a/pandas/util/_test_decorators.py b/pandas/util/_test_decorators.py index 3fe4b8c3bb783..0b2d50d06a66c 100644 --- a/pandas/util/_test_decorators.py +++ b/pandas/util/_test_decorators.py @@ -94,6 +94,38 @@ def _skip_if_not_us_locale(): return True +def skip_if_no(package, min_version=None): + """ + Generic function to help skip test functions when required packages are not + present on the testing system. + + Intended for use as a decorator, this function will wrap the decorated + function with a pytest ``skip_if`` mark. During a pytest test suite + execution, that mark will attempt to import the specified ``package`` and + optionally ensure it meets the ``min_version``. If the import and version + check are unsuccessful, then the decorated function will be skipped. + + Parameters + ---------- + package: str + The name of the package required by the decorated function + min_version: str or None, default None + Optional minimum version of the package required by the decorated + function + + Returns + ------- + decorated_func: function + The decorated function wrapped within a pytest ``skip_if`` mark + """ + def decorated_func(func): + return pytest.mark.skipif( + not safe_import(package, min_version=min_version), + reason="Could not import '{}'".format(package) + )(func) + return decorated_func + + skip_if_no_mpl = pytest.mark.skipif(_skip_if_no_mpl(), reason="Missing matplotlib dependency") skip_if_mpl_1_5 = pytest.mark.skipif(_skip_if_mpl_1_5(), diff --git a/pandas/util/testing.py b/pandas/util/testing.py index 32f8c4884c99f..2a0a7c9301752 100644 --- a/pandas/util/testing.py +++ b/pandas/util/testing.py @@ -359,22 +359,6 @@ def _skip_if_no_xarray(): pytest.skip("xarray version is too low: {version}".format(version=v)) -def _skip_if_no_pathlib(): - try: - from pathlib import Path # noqa - except ImportError: - import pytest - pytest.skip("pathlib not available") - - -def _skip_if_no_localpath(): - try: - from py.path import local as LocalPath # noqa - except ImportError: - import pytest - pytest.skip("py.path not installed") - - def skip_if_no_ne(engine='numexpr'): from pandas.core.computation.expressions import ( _USE_NUMEXPR,