Skip to content

Commit 9923305

Browse files
committed
Fix the rendering of Polars Struct
1 parent f304c66 commit 9923305

File tree

4 files changed

+31
-5
lines changed

4 files changed

+31
-5
lines changed

docs/changelog.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
ITables ChangeLog
22
=================
33

4-
2.4.0-dev
5-
---------------------
4+
2.4.0 (2025-05-17)
5+
------------------
66

77
**Added**
88
- The ITable widget, and the ITable components for Dash and Streamlit have the same features as the `show` function. They can show non-finite floats, bigints, Pandas Style objects and use custom JavaScript formatters ([#374](https://github.com/mwouts/itables/issues/374))
@@ -18,6 +18,7 @@ ITables ChangeLog
1818

1919
**Fixed**
2020
- We have added a new option `text_in_header_can_be_selected` (defaults to `True`). With that option the text in headers can be selected, giving you the option to select and copy the column names back to your Python code.
21+
- We have fixed the rendering of Polars Struct columns ([#290](https://github.com/mwouts/itables/issues/290))
2122

2223

2324
2.3.0 (2025-04-05)

src/itables/datatables_format.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,19 @@ def datatables_rows(
138138
)
139139
except AttributeError:
140140
# Polars DataFrame
141+
assert pl is not None
142+
143+
# Convert Polars Struct to string #290
144+
if any(isinstance(df[col].dtype, pl.Struct) for col in df.columns):
145+
columns = {col: df[col] for col in df.columns}
146+
for col in df.columns:
147+
if isinstance(df[col].dtype, pl.Struct):
148+
try:
149+
columns[col] = df[col].cast(str)
150+
except pl.exceptions.InvalidOperationError:
151+
columns[col] = [str(x) for x in df[col]]
152+
df = pl.DataFrame(columns)
153+
141154
data = df.rows()
142155
data = [[escape_non_finite_float(f) for f in row] for row in data]
143156

src/itables/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""ITables' version number"""
22

3-
__version__ = "2.4.0-dev"
3+
__version__ = "2.4.0"

tests/test_polars.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from itables.sample_dfs import get_dict_of_test_dfs, get_dict_of_test_series
66

77
try:
8-
import polars # noqa
8+
import polars as pl # noqa
99
except ImportError as e:
1010
pytest.skip(str(e), allow_module_level=True)
1111

@@ -26,7 +26,7 @@ def test_show_polars_df(name, df):
2626

2727
def test_encode_mixed_contents():
2828
# Make sure that the bigint escape works for mixed content # 291
29-
df = polars.DataFrame(
29+
df = pl.DataFrame(
3030
{
3131
"bigint": [1666767918216000000],
3232
"int": [1699300000000],
@@ -38,3 +38,15 @@ def test_encode_mixed_contents():
3838
datatables_rows(df)
3939
== "[[1666767918216000000, 1699300000000, 0.9510565400123596, -0.30901700258255005]]"
4040
)
41+
42+
43+
def test_render_polars_struct():
44+
df = pl.DataFrame(
45+
{
46+
"X": ["A", "A", "B", "C", "C", "C"],
47+
}
48+
)
49+
assert (
50+
datatables_rows(df.select(pl.col("X").value_counts(sort=True)))
51+
== '[["{\\"C\\",3}"], ["{\\"A\\",2}"], ["{\\"B\\",1}"]]'
52+
)

0 commit comments

Comments
 (0)