nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: pandas-dev/pandas
Pull request #56199 (2023-11-27 02:43:13)

Backport PR #56194 on branch 2.1.x (BUG: hdf can't deal with ea dtype columns)
Backport PR #56194: BUG: hdf can't deal with ea dtype columns


Patch:
diff --git a/doc/source/whatsnew/v2.1.4.rst b/doc/source/whatsnew/v2.1.4.rst
index eb28e42d30..684b68baa1 100644
--- a/doc/source/whatsnew/v2.1.4.rst
+++ b/doc/source/whatsnew/v2.1.4.rst
@@ -24,6 +24,7 @@ Bug fixes
 - Bug in :meth:`DataFrame.apply` where passing ``raw=True`` ignored ``args`` passed to the applied function (:issue:`55753`)
 - Bug in :meth:`Index.__getitem__` returning wrong result for Arrow dtypes and negative stepsize (:issue:`55832`)
 - Fixed bug in :meth:`DataFrame.__setitem__` casting :class:`Index` with object-dtype to PyArrow backed strings when ``infer_string`` option is set (:issue:`55638`)
+- Fixed bug in :meth:`DataFrame.to_hdf` raising when columns have ``StringDtype`` (:issue:`55088`)
 - Fixed bug in :meth:`Index.insert` casting object-dtype to PyArrow backed strings when ``infer_string`` option is set (:issue:`55638`)
 - Fixed bug in :meth:`Series.str.translate` losing object dtype when string option is set (:issue:`56152`)
 
diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py
index d3055f0ad2..2a72f7d32b 100644
--- a/pandas/io/pytables.py
+++ b/pandas/io/pytables.py
@@ -56,7 +56,6 @@ from pandas.core.dtypes.common import (
     is_bool_dtype,
     is_complex_dtype,
     is_list_like,
-    is_object_dtype,
     is_string_dtype,
     needs_i8_conversion,
 )
@@ -2645,7 +2644,7 @@ class DataIndexableCol(DataCol):
     is_data_indexable = True
 
     def validate_names(self) -> None:
-        if not is_object_dtype(Index(self.values).dtype):
+        if not is_string_dtype(Index(self.values).dtype):
             # TODO: should the message here be more specifically non-str?
             raise ValueError("cannot have non-object label DataIndexableCol")
 


Test patch:
diff --git a/pandas/tests/io/pytables/test_round_trip.py b/pandas/tests/io/pytables/test_round_trip.py
index 085db5f521..3bc8c0c4f8 100644
--- a/pandas/tests/io/pytables/test_round_trip.py
+++ b/pandas/tests/io/pytables/test_round_trip.py
@@ -526,3 +526,18 @@ def test_round_trip_equals(tmp_path, setup_path):
     tm.assert_frame_equal(df, other)
     assert df.equals(other)
     assert other.equals(df)
+
+
+def test_infer_string_columns(tmp_path, setup_path):
+    # GH#
+    pytest.importorskip("pyarrow")
+    path = tmp_path / setup_path
+    with pd.option_context("future.infer_string", True):
+        df = DataFrame(1, columns=list("ABCD"), index=list(range(10))).set_index(
+            ["A", "B"]
+        )
+        expected = df.copy()
+        df.to_hdf(path, key="df", format="table")
+
+        result = read_hdf(path, "df")
+        tm.assert_frame_equal(result, expected)