Skip to content

Commit 52484a2

Browse files
committed
Test Ibis dataframes
1 parent 0e1f293 commit 52484a2

File tree

5 files changed

+261
-2
lines changed

5 files changed

+261
-2
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,12 @@ jobs:
5656
numpy-version: '<2.0'
5757
- python-version: "3.13"
5858
pandas-version: pre
59-
- python-version: "3.12"
60-
modifiers: "modin"
6159
- python-version: "3.13"
6260
modifiers: "polars"
61+
- python-version: "3.13"
62+
modifiers: "ibis"
63+
- python-version: "3.12"
64+
modifiers: "modin"
6365
- python-version: "3.13"
6466
modifiers: "uninstall_narwhals"
6567
- python-version: "3.13"
@@ -97,6 +99,10 @@ jobs:
9799
if: matrix.modifiers == 'polars'
98100
run: pip install polars
99101

102+
- name: Install ibis
103+
if: matrix.modifiers == 'ibis'
104+
run: pip install 'ibis-framework[duckdb]'
105+
100106
- name: Install modin
101107
if: matrix.modifiers == 'modin'
102108
run: pip install modin[all]

docs/ibis_dataframes.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
---
2+
jupytext:
3+
formats: md:myst
4+
notebook_metadata_filter: -jupytext.text_representation.jupytext_version
5+
text_representation:
6+
extension: .md
7+
format_name: myst
8+
format_version: 0.13
9+
kernelspec:
10+
display_name: itables
11+
language: python
12+
name: itables
13+
---
14+
15+
# Sample dataframes
16+
17+
In this notebook we make sure that our test [Ibis](https://ibis-project.org/) dataframes are displayed nicely with the default `itables` settings.
18+
19+
```{code-cell}
20+
from itables import init_notebook_mode, show
21+
from itables.sample_dfs import get_dict_of_test_ibis_dfs
22+
23+
dict_of_test_dfs = get_dict_of_test_ibis_dfs()
24+
init_notebook_mode(all_interactive=True)
25+
```
26+
27+
## empty
28+
29+
```{code-cell}
30+
show(dict_of_test_dfs["empty"])
31+
```
32+
33+
## No rows
34+
35+
```{code-cell}
36+
show(dict_of_test_dfs["no_rows"])
37+
```
38+
39+
## No rows one column
40+
41+
```{code-cell}
42+
show(dict_of_test_dfs["no_rows_one_column"])
43+
```
44+
45+
## No columns
46+
47+
```{code-cell}
48+
show(dict_of_test_dfs["no_columns"])
49+
```
50+
51+
## No columns one row
52+
53+
```{code-cell}
54+
show(dict_of_test_dfs["no_columns_one_row"])
55+
```
56+
57+
## bool
58+
59+
```{code-cell}
60+
show(dict_of_test_dfs["bool"])
61+
```
62+
63+
## Nullable boolean
64+
65+
```{code-cell}
66+
show(dict_of_test_dfs["nullable_boolean"])
67+
```
68+
69+
## int
70+
71+
```{code-cell}
72+
show(dict_of_test_dfs["int"])
73+
```
74+
75+
## Nullable integer
76+
77+
```{code-cell}
78+
show(dict_of_test_dfs["nullable_int"])
79+
```
80+
81+
## float
82+
83+
```{code-cell}
84+
show(dict_of_test_dfs["float"])
85+
```
86+
87+
## str
88+
89+
```{code-cell}
90+
show(dict_of_test_dfs["str"])
91+
```
92+
93+
## time
94+
95+
```{code-cell}
96+
show(dict_of_test_dfs["time"])
97+
```
98+
99+
## object
100+
101+
```{code-cell}
102+
show(dict_of_test_dfs["object"])
103+
```
104+
105+
## ordered_categories
106+
107+
```{code-cell}
108+
show(dict_of_test_dfs["ordered_categories"])
109+
```
110+
111+
## ordered_categories_in_multiindex
112+
113+
```{code-cell}
114+
show(dict_of_test_dfs["ordered_categories_in_multiindex"])
115+
```
116+
117+
## multiindex
118+
119+
```{code-cell}
120+
show(dict_of_test_dfs["multiindex"])
121+
```
122+
123+
## countries
124+
125+
```{code-cell}
126+
:tags: [full-width]
127+
128+
show(dict_of_test_dfs["countries"])
129+
```
130+
131+
## capital
132+
133+
```{code-cell}
134+
show(dict_of_test_dfs["capital"])
135+
```
136+
137+
## complex_index
138+
139+
```{code-cell}
140+
:tags: [full-width]
141+
142+
show(dict_of_test_dfs["complex_index"])
143+
```
144+
145+
## int_float_str
146+
147+
```{code-cell}
148+
show(dict_of_test_dfs["int_float_str"])
149+
```
150+
151+
## wide
152+
153+
```{code-cell}
154+
:tags: [full-width]
155+
156+
show(dict_of_test_dfs["wide"], maxBytes=100000, maxColumns=100, scrollX=True)
157+
```
158+
159+
## long_column_names
160+
161+
```{code-cell}
162+
:tags: [full-width]
163+
164+
show(dict_of_test_dfs["long_column_names"], scrollX=True)
165+
```
166+
167+
## duplicated_columns
168+
169+
```{code-cell}
170+
show(dict_of_test_dfs["duplicated_columns"])
171+
```
172+
173+
## named_column_index
174+
175+
```{code-cell}
176+
show(dict_of_test_dfs["named_column_index"])
177+
```
178+
179+
## big_integers
180+
181+
```{code-cell}
182+
show(dict_of_test_dfs["big_integers"])
183+
```

environment.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ dependencies:
3232
- polars
3333
- pyarrow
3434

35+
# Ibis
36+
- ibis-duckdb
37+
3538
# Modin
3639
- modin-ray
3740

src/itables/sample_dfs.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,26 @@ def get_dict_of_test_polars_dfs(**kwargs):
284284
return polars_dfs
285285

286286

287+
def get_dict_of_test_ibis_dfs(**kwargs):
288+
289+
import ibis
290+
291+
ibis_dfs = {}
292+
293+
t = ibis.table(dict(one="string", two="float", three="int32"), name="my_data")
294+
ibis_dfs["table"] = t
295+
296+
ibis_dfs["table_select"] = t.select("two", "one")
297+
298+
for key, df in get_dict_of_test_dfs(**kwargs).items():
299+
try:
300+
ibis_dfs[key] = ibis.memtable(df)
301+
except (TypeError, ibis.common.exceptions.IbisInputError):
302+
pass
303+
304+
return ibis_dfs
305+
306+
287307
def get_dict_of_test_modin_dfs(**kwargs):
288308

289309
import modin.pandas as mpd
@@ -336,6 +356,10 @@ def get_dict_of_test_polars_series():
336356
return polars_series
337357

338358

359+
def get_dict_of_test_ibis_series():
360+
return {name: value for name, value in get_dict_of_test_ibis_dfs().items()}
361+
362+
339363
def get_dict_of_test_modin_series():
340364
import modin.pandas as mpd
341365

tests/test_ibis.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import pytest
2+
3+
from itables import to_html_datatable
4+
from itables.javascript import datatables_rows
5+
from itables.sample_dfs import get_dict_of_test_ibis_dfs, get_dict_of_test_ibis_series
6+
7+
pl = pytest.importorskip("ibis")
8+
9+
10+
@pytest.fixture(params=get_dict_of_test_ibis_dfs().items(), ids=lambda param: param[0])
11+
def df(request):
12+
return request.param[1]
13+
14+
15+
@pytest.fixture(
16+
params=get_dict_of_test_ibis_series().items(), ids=lambda param: param[0]
17+
)
18+
def x(request):
19+
return request.param[1]
20+
21+
22+
def test_show_ibis_series(x, use_to_html):
23+
to_html_datatable(x, use_to_html)
24+
25+
26+
def test_show_ibis_df(df, use_to_html):
27+
to_html_datatable(df, use_to_html)
28+
29+
30+
def test_encode_mixed_contents():
31+
# Make sure that the bigint escape works for mixed content # 291
32+
df = pl.DataFrame(
33+
{
34+
"bigint": [1666767918216000000],
35+
"int": [1699300000000],
36+
"float": [0.9510565400123596],
37+
"neg": [-0.30901700258255005],
38+
}
39+
)
40+
assert (
41+
datatables_rows(df)
42+
== '[[BigInt("1666767918216000000"), 1699300000000, 0.9510565400123596, -0.30901700258255005]]'
43+
)

0 commit comments

Comments
 (0)