|
17 | 17 | from pandas.compat import is_platform_windows
|
18 | 18 | import pandas.util._test_decorators as td
|
19 | 19 |
|
| 20 | +import pandas as pd |
20 | 21 | from pandas import (
|
| 22 | + NA, |
21 | 23 | DataFrame,
|
22 | 24 | MultiIndex,
|
23 | 25 | Series,
|
|
27 | 29 | to_datetime,
|
28 | 30 | )
|
29 | 31 | import pandas._testing as tm
|
| 32 | +from pandas.core.arrays import ( |
| 33 | + ArrowStringArray, |
| 34 | + StringArray, |
| 35 | +) |
30 | 36 |
|
31 | 37 | from pandas.io.common import file_path_to_url
|
32 | 38 | import pandas.io.html
|
@@ -132,6 +138,64 @@ def test_to_html_compat(self):
|
132 | 138 | res = self.read_html(out, attrs={"class": "dataframe"}, index_col=0)[0]
|
133 | 139 | tm.assert_frame_equal(res, df)
|
134 | 140 |
|
| 141 | + @pytest.mark.parametrize("dtype_backend", ["pandas", "pyarrow"]) |
| 142 | + @pytest.mark.parametrize("storage", ["python", "pyarrow"]) |
| 143 | + def test_use_nullable_dtypes(self, storage, dtype_backend): |
| 144 | + # GH#50286 |
| 145 | + df = DataFrame( |
| 146 | + { |
| 147 | + "a": Series([1, np.nan, 3], dtype="Int64"), |
| 148 | + "b": Series([1, 2, 3], dtype="Int64"), |
| 149 | + "c": Series([1.5, np.nan, 2.5], dtype="Float64"), |
| 150 | + "d": Series([1.5, 2.0, 2.5], dtype="Float64"), |
| 151 | + "e": [True, False, None], |
| 152 | + "f": [True, False, True], |
| 153 | + "g": ["a", "b", "c"], |
| 154 | + "h": ["a", "b", None], |
| 155 | + } |
| 156 | + ) |
| 157 | + |
| 158 | + if storage == "python": |
| 159 | + string_array = StringArray(np.array(["a", "b", "c"], dtype=np.object_)) |
| 160 | + string_array_na = StringArray(np.array(["a", "b", NA], dtype=np.object_)) |
| 161 | + |
| 162 | + else: |
| 163 | + pa = pytest.importorskip("pyarrow") |
| 164 | + string_array = ArrowStringArray(pa.array(["a", "b", "c"])) |
| 165 | + string_array_na = ArrowStringArray(pa.array(["a", "b", None])) |
| 166 | + |
| 167 | + out = df.to_html(index=False) |
| 168 | + with pd.option_context("mode.string_storage", storage): |
| 169 | + with pd.option_context("mode.dtype_backend", dtype_backend): |
| 170 | + result = self.read_html(out, use_nullable_dtypes=True)[0] |
| 171 | + |
| 172 | + expected = DataFrame( |
| 173 | + { |
| 174 | + "a": Series([1, np.nan, 3], dtype="Int64"), |
| 175 | + "b": Series([1, 2, 3], dtype="Int64"), |
| 176 | + "c": Series([1.5, np.nan, 2.5], dtype="Float64"), |
| 177 | + "d": Series([1.5, 2.0, 2.5], dtype="Float64"), |
| 178 | + "e": Series([True, False, NA], dtype="boolean"), |
| 179 | + "f": Series([True, False, True], dtype="boolean"), |
| 180 | + "g": string_array, |
| 181 | + "h": string_array_na, |
| 182 | + } |
| 183 | + ) |
| 184 | + |
| 185 | + if dtype_backend == "pyarrow": |
| 186 | + import pyarrow as pa |
| 187 | + |
| 188 | + from pandas.arrays import ArrowExtensionArray |
| 189 | + |
| 190 | + expected = DataFrame( |
| 191 | + { |
| 192 | + col: ArrowExtensionArray(pa.array(expected[col], from_pandas=True)) |
| 193 | + for col in expected.columns |
| 194 | + } |
| 195 | + ) |
| 196 | + |
| 197 | + tm.assert_frame_equal(result, expected) |
| 198 | + |
135 | 199 | @pytest.mark.network
|
136 | 200 | @tm.network(
|
137 | 201 | url=(
|
|
0 commit comments