From 754003d2d25d8f35a2b6d25ce9a8848350255a0c Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Wed, 13 Dec 2017 09:45:17 -0500 Subject: [PATCH 1/3] Created generic skip_if_no dec; converted pathlib decs --- pandas/tests/io/sas/test_sas7bdat.py | 3 ++- pandas/tests/io/test_common.py | 4 ++-- pandas/tests/io/test_excel.py | 4 ++-- pandas/util/_test_decorators.py | 7 +++++++ pandas/util/testing.py | 8 -------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pandas/tests/io/sas/test_sas7bdat.py b/pandas/tests/io/sas/test_sas7bdat.py index c059f01ecf3f4..b46fee2b51b26 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] diff --git a/pandas/tests/io/test_common.py b/pandas/tests/io/test_common.py index 707580bfe9601..d19f084900acc 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,9 +68,8 @@ 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')) diff --git a/pandas/tests/io/test_excel.py b/pandas/tests/io/test_excel.py index 4efeeecf8ee4a..aff0124a164b4 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) diff --git a/pandas/util/_test_decorators.py b/pandas/util/_test_decorators.py index 3fe4b8c3bb783..bcc42d4277ab4 100644 --- a/pandas/util/_test_decorators.py +++ b/pandas/util/_test_decorators.py @@ -94,6 +94,13 @@ def _skip_if_not_us_locale(): return True +def skip_if_no(package, min_version=None): + 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..9b41df9e3d9af 100644 --- a/pandas/util/testing.py +++ b/pandas/util/testing.py @@ -359,14 +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 From 4500f98367499e2eb46bbb1e8a252e77fe6f042e Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Wed, 13 Dec 2017 10:02:47 -0500 Subject: [PATCH 2/3] Localpath skip decorator --- pandas/tests/io/sas/test_sas7bdat.py | 2 +- pandas/tests/io/test_common.py | 3 +-- pandas/tests/io/test_excel.py | 3 +-- pandas/tests/io/test_pytables.py | 6 ++---- pandas/util/_test_decorators.py | 6 ++++-- pandas/util/testing.py | 8 -------- 6 files changed, 9 insertions(+), 19 deletions(-) diff --git a/pandas/tests/io/sas/test_sas7bdat.py b/pandas/tests/io/sas/test_sas7bdat.py index b46fee2b51b26..5da347e47957c 100644 --- a/pandas/tests/io/sas/test_sas7bdat.py +++ b/pandas/tests/io/sas/test_sas7bdat.py @@ -83,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 d19f084900acc..13a393d9109ae 100644 --- a/pandas/tests/io/test_common.py +++ b/pandas/tests/io/test_common.py @@ -75,9 +75,8 @@ def test_stringify_path_pathlib(self): 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 aff0124a164b4..274d60c40e83f 100644 --- a/pandas/tests/io/test_excel.py +++ b/pandas/tests/io/test_excel.py @@ -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 bcc42d4277ab4..c47189114ad7d 100644 --- a/pandas/util/_test_decorators.py +++ b/pandas/util/_test_decorators.py @@ -96,8 +96,10 @@ def _skip_if_not_us_locale(): def skip_if_no(package, min_version=None): def decorated_func(func): - return pytest.mark.skipif(not safe_import(package, min_version=min_version), - reason="Could not import '{}'".format(package))(func) + return pytest.mark.skipif( + not safe_import(package, min_version=min_version), + reason="Could not import '{}'".format(package) + )(func) return decorated_func diff --git a/pandas/util/testing.py b/pandas/util/testing.py index 9b41df9e3d9af..2a0a7c9301752 100644 --- a/pandas/util/testing.py +++ b/pandas/util/testing.py @@ -359,14 +359,6 @@ def _skip_if_no_xarray(): pytest.skip("xarray version is too low: {version}".format(version=v)) -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, From 53d57378389546e7cb8b3eaadb11ef4d67d02de6 Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Thu, 14 Dec 2017 08:47:10 -0500 Subject: [PATCH 3/3] Added docstring to skip_if_no function --- pandas/util/_test_decorators.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pandas/util/_test_decorators.py b/pandas/util/_test_decorators.py index c47189114ad7d..0b2d50d06a66c 100644 --- a/pandas/util/_test_decorators.py +++ b/pandas/util/_test_decorators.py @@ -95,6 +95,29 @@ def _skip_if_not_us_locale(): 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),