diff --git a/src/ydata_profiling/model/pandas/summary_pandas.py b/src/ydata_profiling/model/pandas/summary_pandas.py index f392752df..927ffacaf 100644 --- a/src/ydata_profiling/model/pandas/summary_pandas.py +++ b/src/ydata_profiling/model/pandas/summary_pandas.py @@ -13,6 +13,7 @@ from ydata_profiling.model.summarizer import BaseSummarizer from ydata_profiling.model.summary import describe_1d, get_series_descriptions from ydata_profiling.model.typeset import ProfilingTypeSet +from ydata_profiling.utils.compat import optional_option_context from ydata_profiling.utils.dataframe import sort_column_names @@ -44,7 +45,7 @@ def pandas_describe_1d( """ # Make sure pd.NA is not in the series - with pd.option_context("future.no_silent_downcasting", True): + with optional_option_context("future.no_silent_downcasting", True): series = series.fillna(np.nan) has_cast_type = _is_cast_type_defined(typeset, series.name) diff --git a/src/ydata_profiling/utils/compat.py b/src/ydata_profiling/utils/compat.py index 879316e99..b01c7db55 100644 --- a/src/ydata_profiling/utils/compat.py +++ b/src/ydata_profiling/utils/compat.py @@ -1,4 +1,6 @@ """Utility functions for (version) compatibility""" + +from contextlib import contextmanager from functools import lru_cache from typing import Tuple @@ -12,3 +14,16 @@ def pandas_version_info() -> Tuple[int, ...]: akin to `sys.version_info` for the Python version. """ return tuple(int(s) for s in pd.__version__.split(".")) + + +@contextmanager +def optional_option_context(option_key, value): + """ + A context manager that sets an option only if it is available in the + current pandas version; otherwise, it is a no-op. + """ + try: + with pd.option_context(option_key, value): + yield + except pd.errors.OptionError: + yield diff --git a/tests/unit/test_pd_future_infer_string.py b/tests/unit/test_pd_future_infer_string.py index ca9838029..aa37d121b 100644 --- a/tests/unit/test_pd_future_infer_string.py +++ b/tests/unit/test_pd_future_infer_string.py @@ -2,6 +2,7 @@ import pytest from ydata_profiling import ProfileReport +from ydata_profiling.utils.compat import pandas_version_info @pytest.fixture() @@ -15,6 +16,9 @@ def df(): return df +@pytest.mark.skipif( + pandas_version_info() < (2, 1, 0), reason="requires pandas 2.1 or higher" +) def test_pd_future_infer_string(df: pd.DataFrame): with pd.option_context("future.infer_string", True): profile_report = ProfileReport(df, title="Test Report", progress_bar=False)