diff --git a/LICENSE b/LICENSE
index 032fa1a1..499aa224 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2019-2023 Marc Wouts
+Copyright (c) 2019-2024 Marc Wouts
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/docs/changelog.md b/docs/changelog.md
index 96145cfc..bc9f3079 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,6 +1,17 @@
ITables ChangeLog
=================
+1.6.4 (2024-02-03)
+------------------
+
+**Fixed**
+- Complex table footers are now in the correct order ([#219](https://github.com/mwouts/itables/issues/219))
+- We have adjusted the test suite for `pandas==2.2.0`
+([#223](https://github.com/mwouts/itables/issues/223),
+[pandas-57229](https://github.com/pandas-dev/pandas/issues/57229),
+[pandas-55080](https://github.com/pandas-dev/pandas/issues/55080))
+
+
1.6.3 (2023-12-10)
------------------
diff --git a/environment2.yml b/environment2.yml
deleted file mode 100644
index 53cb13b2..00000000
--- a/environment2.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: itables2
-channels:
- - conda-forge
- - defaults
-dependencies:
- - python<3
- - IPython
- - pandas==0.22
- - pytest
- - pytest-xdist
- - pytest-cov
- - pathlib
- - functools32
- - pip
- - pip:
- - world_bank_data
- - jupytext
diff --git a/itables/javascript.py b/itables/javascript.py
index 761783d1..284d4de6 100644
--- a/itables/javascript.py
+++ b/itables/javascript.py
@@ -154,16 +154,6 @@ def _table_header(
if not show_index and len(df.columns):
thead = thead.replace("
| ", "", 1)
- if column_filters:
- # We use this header in the column filters, so we need to remove any column multiindex first"""
- thead_flat = ""
- if show_index:
- for index in df.index.names:
- thead_flat += "{} | ".format(index)
-
- for column in df.columns:
- thead_flat += "{} | ".format(column)
-
loading = "Loading... (need help?) | "
tbody = "{}
".format(loading)
@@ -172,15 +162,14 @@ def _table_header(
else:
style = ""
- if column_filters == "header":
- header = "{}".format(thead_flat)
- else:
- header = "{}".format(thead)
+ header = "{}".format(
+ _flat_header(df, show_index) if column_filters == "header" else thead
+ )
if column_filters == "footer":
- footer = "{}".format(thead_flat)
+ footer = "{}".format(_flat_header(df, show_index))
elif footer:
- footer = "{}".format(thead)
+ footer = "{}".format(_tfoot_from_thead(thead))
else:
footer = ""
@@ -195,6 +184,27 @@ def _table_header(
)
+def _flat_header(df, show_index):
+ """When column filters are shown, we need to remove any column multiindex"""
+ header = ""
+ if show_index:
+ for index in df.index.names:
+ header += "{} | ".format(index)
+
+ for column in df.columns:
+ header += "{} | ".format(column)
+
+ return header
+
+
+def _tfoot_from_thead(thead):
+ header_rows = thead.split("")
+ last_row = header_rows[-1]
+ assert not last_row.strip(), last_row
+ header_rows = header_rows[:-1]
+ return "".join(row + "" for row in header_rows[::-1] if "= "2.2.0":
+ # https://github.com/pandas-dev/pandas/issues/55080 is back in 2.2.0?
+ return pd.Series(pd.date_range("1970-01-01", "2099-12-31", freq="D"))
return pd.Series(pd.date_range("1677-09-23", "2262-04-10", freq="D"))
diff --git a/itables/version.py b/itables/version.py
index 6557b260..d341f359 100644
--- a/itables/version.py
+++ b/itables/version.py
@@ -1,3 +1,3 @@
"""ITables' version number"""
-__version__ = "1.6.3"
+__version__ = "1.6.4"
diff --git a/tests/test_documentation_notebooks_run.py b/tests/test_documentation_notebooks_run.py
index 38eeea8a..7292e982 100644
--- a/tests/test_documentation_notebooks_run.py
+++ b/tests/test_documentation_notebooks_run.py
@@ -27,9 +27,9 @@ def list_doc_notebooks():
)
def test_run_documentation_notebooks(notebook):
if "polars" in notebook.stem and pl is None:
- pytest.skip(msg="Polars is not available")
+ pytest.skip("Polars is not available")
if "pandas_style" in notebook.stem and pd_style is None:
- pytest.skip(msg="Pandas Style is not available")
+ pytest.skip("Pandas Style is not available")
nb = jupytext.read(notebook)
py_notebook = jupytext.writes(nb, "py:percent")
diff --git a/tests/test_javascript.py b/tests/test_javascript.py
index 9e45108f..2da848a1 100644
--- a/tests/test_javascript.py
+++ b/tests/test_javascript.py
@@ -1,6 +1,11 @@
import pytest
-from itables.javascript import _df_fits_in_one_page, replace_value, to_html_datatable
+from itables.javascript import (
+ _df_fits_in_one_page,
+ _tfoot_from_thead,
+ replace_value,
+ to_html_datatable,
+)
def test_replace_value(
@@ -46,3 +51,48 @@ def test_df_fits_in_one_page(df, lengthMenu):
min_rows = min_rows[0]
assert _df_fits_in_one_page(df, kwargs) == (len(df) <= min_rows)
+
+
+def test_tfoot_from_thead(
+ thead="""
+
+ |
+ region |
+ country |
+ capital |
+ longitude |
+ latitude |
+ flag |
+
+
+ code |
+ |
+ |
+ |
+ |
+ |
+ |
+
+""",
+ expected_tfoot="""
+
+ code |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+ |
+ region |
+ country |
+ capital |
+ longitude |
+ latitude |
+ flag |
+
+""",
+):
+ assert _tfoot_from_thead(thead) == expected_tfoot
diff --git a/tests/test_sample_dfs.py b/tests/test_sample_dfs.py
index 77f9feee..9211954a 100644
--- a/tests/test_sample_dfs.py
+++ b/tests/test_sample_dfs.py
@@ -25,6 +25,10 @@
pytest.mark.filterwarnings("error"),
# Seen on the CI on Py38 and Py39
pytest.mark.filterwarnings("ignore::ResourceWarning"),
+ # TODO: https://github.com/mwouts/itables/issues/223
+ pytest.mark.filterwarnings(
+ "ignore:Setting an item of incompatible dtype is deprecated:FutureWarning"
+ ),
]
if PANDAS_VERSION_MAJOR < 2: