diff --git a/docs/source/python/api/formats.rst b/docs/source/python/api/formats.rst index 0d2cd8975cde..57a5e824fab1 100644 --- a/docs/source/python/api/formats.rst +++ b/docs/source/python/api/formats.rst @@ -42,14 +42,11 @@ CSV Files .. _api.feather: -Feather Files (Deprecated) --------------------------- +Feather Files +------------- .. currentmodule:: pyarrow.feather -.. deprecated:: 24.0.0 - The Feather API is deprecated. Use the :ref:`IPC ` API instead. - .. autosummary:: :toctree: ../generated/ diff --git a/docs/source/python/feather.rst b/docs/source/python/feather.rst index 76520e912b67..c624ea8927f5 100644 --- a/docs/source/python/feather.rst +++ b/docs/source/python/feather.rst @@ -22,10 +22,6 @@ Feather File Format =================== -.. deprecated:: 24.0.0 - The ``pyarrow.feather`` module is deprecated. Feather V2 is the Arrow IPC - file format. Use :mod:`pyarrow.ipc` instead. See :ref:`ipc` for details. - Feather is a portable file format for storing Arrow tables or data frames (from languages like Python or R) that utilizes the :ref:`Arrow IPC format ` internally. Feather was created early in the Arrow project as a proof of @@ -39,8 +35,8 @@ R. There are two file format versions for Feather: * Version 1 (V1), a legacy version available starting in 2016, replaced by V2. V1 files are distinct from Arrow IPC files and lack many features, such as the ability to store all Arrow data types. V1 files also lack compression - support. We intend to maintain read support for V1 for the foreseeable - future. + support. Reading and writing V1 files is deprecated as of 25.0.0 and will + be removed in a future version. The ``pyarrow.feather`` module contains the read and write functions for the format. :func:`~pyarrow.feather.write_feather` accepts either a @@ -108,9 +104,13 @@ reduced disk IO requirements. Writing Version 1 (V1) Files ---------------------------- +.. deprecated:: 25.0.0 + Support for the legacy Feather V1 format is deprecated. Reading and + writing V1 files will be removed in a future version. Rewrite V1 files + in the Arrow IPC file format (Feather V2). + For compatibility with libraries without support for Version 2 files, you can -write the version 1 format by passing ``version=1`` to ``write_feather``. We -intend to maintain read support for V1 for the foreseeable future. +write the version 1 format by passing ``version=1`` to ``write_feather``. Migration to IPC ---------------- diff --git a/python/pyarrow/feather.py b/python/pyarrow/feather.py index 68f708c91489..1c95bf1ebbec 100644 --- a/python/pyarrow/feather.py +++ b/python/pyarrow/feather.py @@ -32,9 +32,6 @@ class FeatherDataset: """ Encapsulates details of reading a list of Feather files. - .. deprecated:: 24.0.0 - Use :func:`pyarrow.dataset.dataset` with ``format='ipc'`` instead. - Parameters ---------- path_or_paths : List[str] @@ -44,12 +41,6 @@ class FeatherDataset: """ def __init__(self, path_or_paths, validate_schema=True): - warnings.warn( - "pyarrow.feather.FeatherDataset is deprecated as of 24.0.0. " - "Use pyarrow.dataset.dataset() with format='ipc' instead.", - FutureWarning, - stacklevel=2 - ) self.paths = path_or_paths self.validate_schema = validate_schema @@ -127,11 +118,6 @@ def write_feather(df, dest, compression=None, compression_level=None, """ Write a pandas.DataFrame to Feather format. - .. deprecated:: 24.0.0 - Use :func:`pyarrow.ipc.new_file` / - :class:`pyarrow.ipc.RecordBatchFileWriter` instead. - Feather V2 is the Arrow IPC file format. - Parameters ---------- df : pandas.DataFrame or pyarrow.Table @@ -150,15 +136,20 @@ def write_feather(df, dest, compression=None, compression_level=None, which is currently 64K version : int, default 2 Feather file version. Version 2 is the current. Version 1 is the more - limited legacy format + limited legacy format. + + .. deprecated:: 25.0.0 + Writing Feather V1 files is deprecated. Use the default + ``version=2`` to write Arrow IPC files instead. """ - warnings.warn( - "pyarrow.feather.write_feather is deprecated as of 24.0.0. " - "Use pyarrow.ipc.new_file() / RecordBatchFileWriter instead. " - "Feather V2 is the Arrow IPC file format.", - FutureWarning, - stacklevel=2 - ) + if version == 1: + warnings.warn( + "Feather V1 files are deprecated as of 25.0.0 and support will " + "be removed in a future version. Use the default version=2 to " + "write Arrow IPC files instead.", + FutureWarning, + stacklevel=2 + ) if _pandas_api.have_pandas: if (_pandas_api.has_sparse and isinstance(df, _pandas_api.pd.SparseDataFrame)): @@ -223,11 +214,6 @@ def read_feather(source, columns=None, use_threads=True, Read a pandas.DataFrame from Feather format. To read as pyarrow.Table use feather.read_table. - .. deprecated:: 24.0.0 - Use :func:`pyarrow.ipc.open_file` / - :class:`pyarrow.ipc.RecordBatchFileReader` instead. - Feather V2 is the Arrow IPC file format. - Parameters ---------- source : str file path, or file-like object @@ -249,13 +235,6 @@ def read_feather(source, columns=None, use_threads=True, df : pandas.DataFrame The contents of the Feather file as a pandas.DataFrame """ - warnings.warn( - "pyarrow.feather.read_feather is deprecated as of 24.0.0. " - "Use pyarrow.ipc.open_file() / RecordBatchFileReader instead. " - "Feather V2 is the Arrow IPC file format.", - FutureWarning, - stacklevel=2 - ) return (_read_table_internal( source, columns=columns, memory_map=memory_map, use_threads=use_threads).to_pandas(use_threads=use_threads, **kwargs)) @@ -265,11 +244,20 @@ def _read_table_internal(source, columns=None, memory_map=False, use_threads=True): """ Internal implementation for reading a Feather file as a pyarrow.Table. - Does not emit deprecation warnings. + Emits a deprecation warning if the file is a legacy Feather V1 file. """ reader = _feather.FeatherReader( source, use_memory_map=memory_map, use_threads=use_threads) + if reader.version < 3: + warnings.warn( + "Feather V1 files are deprecated as of 25.0.0 and support will " + "be removed in a future version. Consider rewriting this file " + "in the Arrow IPC file format (Feather V2).", + FutureWarning, + stacklevel=3 + ) + if columns is None: return reader.read() @@ -302,11 +290,6 @@ def read_table(source, columns=None, memory_map=False, use_threads=True): """ Read a pyarrow.Table from Feather format - .. deprecated:: 24.0.0 - Use :func:`pyarrow.ipc.open_file` / - :class:`pyarrow.ipc.RecordBatchFileReader` instead. - Feather V2 is the Arrow IPC file format. - Parameters ---------- source : str file path, or file-like object @@ -324,13 +307,6 @@ def read_table(source, columns=None, memory_map=False, use_threads=True): table : pyarrow.Table The contents of the Feather file as a pyarrow.Table """ - warnings.warn( - "pyarrow.feather.read_table is deprecated as of 24.0.0. " - "Use pyarrow.ipc.open_file() / RecordBatchFileReader instead. " - "Feather V2 is the Arrow IPC file format.", - FutureWarning, - stacklevel=2 - ) return _read_table_internal(source, columns=columns, memory_map=memory_map, use_threads=use_threads) diff --git a/python/pyarrow/tests/test_dataset.py b/python/pyarrow/tests/test_dataset.py index b12a1bce6010..a9263e7153bf 100644 --- a/python/pyarrow/tests/test_dataset.py +++ b/python/pyarrow/tests/test_dataset.py @@ -1927,7 +1927,6 @@ def test_fragments_parquet_subset_with_nested_fields(tempdir): @pytest.mark.pandas @pytest.mark.parquet -@pytest.mark.filterwarnings("ignore:pyarrow.feather:FutureWarning") def test_fragments_repr(tempdir, dataset): # partitioned parquet dataset fragment = list(dataset.get_fragments())[0] @@ -3700,7 +3699,7 @@ def test_column_names_encoding(tempdir, dataset_reader): assert dataset_transcoded.to_table().equals(expected_table) -@pytest.mark.filterwarnings("ignore:pyarrow.feather:FutureWarning") +@pytest.mark.filterwarnings("ignore:Feather V1:FutureWarning") def test_feather_format(tempdir, dataset_reader): from pyarrow.feather import write_feather @@ -4082,7 +4081,6 @@ def test_dataset_project_null_column(tempdir, dataset_reader): assert dataset_reader.to_table(dataset).equals(expected) -@pytest.mark.filterwarnings("ignore:pyarrow.feather:FutureWarning") def test_dataset_project_columns(tempdir, dataset_reader): # basic column re-projection with expressions from pyarrow import feather @@ -4434,7 +4432,6 @@ def test_write_dataset_with_dataset(tempdir): @pytest.mark.pandas -@pytest.mark.filterwarnings("ignore:pyarrow.feather:FutureWarning") def test_write_dataset_existing_data(tempdir): directory = tempdir / 'ds' table = pa.table({'b': ['x', 'y', 'z'], 'c': [1, 2, 3]}) @@ -5099,7 +5096,6 @@ def test_write_dataset_arrow_schema_metadata(tempdir): assert result["a"].type.tz == "Europe/Brussels" -@pytest.mark.filterwarnings("ignore:pyarrow.feather:FutureWarning") def test_write_dataset_schema_metadata(tempdir): # ensure that schema metadata gets written from pyarrow import feather diff --git a/python/pyarrow/tests/test_feather.py b/python/pyarrow/tests/test_feather.py index c04cef534ee3..996147f95821 100644 --- a/python/pyarrow/tests/test_feather.py +++ b/python/pyarrow/tests/test_feather.py @@ -41,10 +41,10 @@ except ImportError: pass -# Suppress deprecation warnings for existing tests since pyarrow.feather -# is deprecated as of 24.0.0 +# Suppress deprecation warnings for existing tests that intentionally +# exercise the deprecated Feather V1 format pytestmark = pytest.mark.filterwarnings( - "ignore:pyarrow.feather:FutureWarning" + "ignore:Feather V1:FutureWarning" ) @@ -894,39 +894,44 @@ def test_feather_datetime_resolution_arrow_to_pandas(tempdir): # --- Deprecation warning tests --- @pytest.mark.pandas -@pytest.mark.filterwarnings("default:pyarrow.feather:FutureWarning") -def test_feather_deprecation_warnings(tempdir): +@pytest.mark.filterwarnings("default:Feather V1:FutureWarning") +def test_feather_v1_deprecation_warnings(tempdir): table = pa.table({"a": [1, 2, 3]}) path = str(tempdir / "test.feather") - with pytest.warns(FutureWarning, match="write_feather is deprecated"): - write_feather(table, path) + with pytest.warns(FutureWarning, match="Feather V1"): + write_feather(table, path, version=1) - with pytest.warns(FutureWarning, match="read_table is deprecated"): + with pytest.warns(FutureWarning, match="Feather V1"): read_table(path) - with pytest.warns(FutureWarning, match="read_feather is deprecated"): + with pytest.warns(FutureWarning, match="Feather V1"): read_feather(path) -@pytest.mark.filterwarnings("default:pyarrow.feather:FutureWarning") -def test_feather_dataset_deprecated(): - with pytest.warns(FutureWarning, match="FeatherDataset is deprecated"): - FeatherDataset([]) +def test_feather_v2_no_deprecation_warning(tempdir): + table = pa.table({"a": [1, 2, 3]}) + path = str(tempdir / "test.feather") + + with warnings.catch_warnings(): + warnings.simplefilter("error", FutureWarning) + write_feather(table, path) + read_table(path) + FeatherDataset([path]).read_table() @pytest.mark.pandas -@pytest.mark.filterwarnings("default:pyarrow.feather:FutureWarning") -def test_read_feather_no_double_warning(tempdir): - """Verify read_feather emits exactly one FutureWarning, not two.""" +@pytest.mark.filterwarnings("default:Feather V1:FutureWarning") +def test_read_feather_v1_no_double_warning(tempdir): + """Verify reading a V1 file emits exactly one FutureWarning, not two.""" table = pa.table({"a": [1, 2, 3]}) path = str(tempdir / "test.feather") with warnings.catch_warnings(): warnings.simplefilter("ignore", FutureWarning) - write_feather(table, path) + write_feather(table, path, version=1) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") read_feather(path) - future_warnings = [x for x in w if issubclass(x.category, - FutureWarning)] - assert len(future_warnings) == 1 + v1_warnings = [x for x in w if issubclass(x.category, + FutureWarning)] + assert len(v1_warnings) == 1