From 500d36c0009596c66e6fef88b59a29a9d219135f Mon Sep 17 00:00:00 2001 From: Marc Wouts Date: Sat, 7 Oct 2023 11:50:34 +0100 Subject: [PATCH] Make the indirect dependency on jinja2 optional (#203) --- .github/workflows/continuous-integration.yml | 6 ++++++ README.md | 2 +- codecov.yml | 4 ++-- docs/changelog.md | 7 +++++++ docs/quick_start.md | 2 +- itables/javascript.py | 20 ++++++++++++++------ itables/version.py | 2 +- tests/test_documentation_notebooks_run.py | 3 +++ tests/test_sample_dfs.py | 5 +++++ 9 files changed, 40 insertions(+), 11 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 58b270cd..3d7ae113 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -50,6 +50,8 @@ jobs: - python-version: "3.11" pandas-version: pre polars: true + - python-version: "3.11" + uninstall_jinja2: true runs-on: ubuntu-20.04 steps: - name: Checkout @@ -83,6 +85,10 @@ jobs: if: matrix.polars run: pip install -e .[polars] + - name: Uninstall jinja2 + if: matrix.uninstall_jinja2 + run: pip uninstall jinja2 -y + - name: Install a Jupyter Kernel run: python -m ipykernel install --name itables --user diff --git a/README.md b/README.md index b41c0866..78c4634e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Interactive Tables -![CI](https://github.com/mwouts/itables/workflows/CI/badge.svg) +![CI](https://github.com/mwouts/itables/actions/workflows/continuous-integration.yml/badge.svg?branch=main) [![codecov.io](https://codecov.io/github/mwouts/itables/coverage.svg?branch=main)](https://codecov.io/github/mwouts/itables?branch=main) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/mwouts/itables.svg)](https://lgtm.com/projects/g/mwouts/itables/context:python) [![Pypi](https://img.shields.io/pypi/v/itables.svg)](https://pypi.python.org/pypi/itables) diff --git a/codecov.yml b/codecov.yml index 408a022c..f9c4a84c 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,9 +1,9 @@ codecov: notify: - after_n_builds: 15 + after_n_builds: 10 comment: - after_n_builds: 15 + after_n_builds: 10 coverage: status: diff --git a/docs/changelog.md b/docs/changelog.md index fba71996..1bec8a1e 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,6 +1,13 @@ ITables ChangeLog ================= +1.6.2 (2023-10-07) +------------------ + +**Fixed** +- We have removed an indirect dependency on `jinja2` caused by the Pandas style objects ([#202](https://github.com/mwouts/itables/issues/202)) + + 1.6.1 (2023-10-01) ------------------ diff --git a/docs/quick_start.md b/docs/quick_start.md index df28f05e..da7a323a 100644 --- a/docs/quick_start.md +++ b/docs/quick_start.md @@ -14,7 +14,7 @@ kernelspec: # Quick Start -![CI](https://github.com/mwouts/itables/workflows/CI/badge.svg) +![CI](https://github.com/mwouts/itables/actions/workflows/continuous-integration.yml/badge.svg?branch=main) [![codecov.io](https://codecov.io/github/mwouts/itables/coverage.svg?branch=main)](https://codecov.io/github/mwouts/itables?branch=main) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/mwouts/itables.svg)](https://lgtm.com/projects/g/mwouts/itables/context:python) [![Pypi](https://img.shields.io/pypi/v/itables.svg)](https://pypi.python.org/pypi/itables) diff --git a/itables/javascript.py b/itables/javascript.py index e9b2fdc5..e601972b 100644 --- a/itables/javascript.py +++ b/itables/javascript.py @@ -10,7 +10,11 @@ import numpy as np import pandas as pd -import pandas.io.formats.style as pd_style + +try: + import pandas.io.formats.style as pd_style +except ImportError: + pd_style = None try: import polars as pl @@ -40,7 +44,9 @@ "warn_on_int_to_str_conversion", } _ORIGINAL_DATAFRAME_REPR_HTML = pd.DataFrame._repr_html_ -_ORIGINAL_DATAFRAME_STYLE_REPR_HTML = pd_style.Styler._repr_html_ +_ORIGINAL_DATAFRAME_STYLE_REPR_HTML = ( + None if pd_style is None else pd_style.Styler._repr_html_ +) _ORIGINAL_POLARS_DATAFRAME_REPR_HTML = pl.DataFrame._repr_html_ _CONNECTED = True @@ -92,12 +98,14 @@ def init_notebook_mode( if all_interactive: pd.DataFrame._repr_html_ = _datatables_repr_ pd.Series._repr_html_ = _datatables_repr_ - pd_style.Styler._repr_html_ = _datatables_repr_ + if pd_style is not None: + pd_style.Styler._repr_html_ = _datatables_repr_ pl.DataFrame._repr_html_ = _datatables_repr_ pl.Series._repr_html_ = _datatables_repr_ else: pd.DataFrame._repr_html_ = _ORIGINAL_DATAFRAME_REPR_HTML - pd_style.Styler._repr_html_ = _ORIGINAL_DATAFRAME_STYLE_REPR_HTML + if pd_style is not None: + pd_style.Styler._repr_html_ = _ORIGINAL_DATAFRAME_STYLE_REPR_HTML pl.DataFrame._repr_html_ = _ORIGINAL_POLARS_DATAFRAME_REPR_HTML if hasattr(pd.Series, "_repr_html_"): del pd.Series._repr_html_ @@ -267,7 +275,7 @@ def to_html_datatable( use_to_html=False, **kwargs ): - if use_to_html or isinstance(df, pd_style.Styler): + if use_to_html or (pd_style is not None and isinstance(df, pd_style.Styler)): return to_html_datatable_using_to_html( df=df, caption=caption, @@ -445,7 +453,7 @@ def to_html_datatable_using_to_html( # default UUID in Pandas styler objects has uuid_len=5 or str(uuid.uuid4())[:5] ) - if isinstance(df, pd_style.Styler): + if pd_style is not None and isinstance(df, pd_style.Styler): if not showIndex: try: df = df.hide() diff --git a/itables/version.py b/itables/version.py index acd2cad8..211dd9d4 100644 --- a/itables/version.py +++ b/itables/version.py @@ -1,3 +1,3 @@ """ITables' version number""" -__version__ = "1.6.1" +__version__ = "1.6.2" diff --git a/tests/test_documentation_notebooks_run.py b/tests/test_documentation_notebooks_run.py index 4193047d..38eeea8a 100644 --- a/tests/test_documentation_notebooks_run.py +++ b/tests/test_documentation_notebooks_run.py @@ -5,6 +5,7 @@ import pytest from itables import init_notebook_mode +from itables.javascript import pd_style try: import polars as pl @@ -27,6 +28,8 @@ 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") + if "pandas_style" in notebook.stem and pd_style is None: + pytest.skip(msg="Pandas Style is not available") nb = jupytext.read(notebook) py_notebook = jupytext.writes(nb, "py:percent") diff --git a/tests/test_sample_dfs.py b/tests/test_sample_dfs.py index 7001f752..77f9feee 100644 --- a/tests/test_sample_dfs.py +++ b/tests/test_sample_dfs.py @@ -6,6 +6,7 @@ from itables import show, to_html_datatable from itables.datatables_format import _format_column, generate_encoder +from itables.javascript import pd_style from itables.sample_dfs import ( COLUMN_TYPES, PANDAS_VERSION_MAJOR, @@ -58,6 +59,10 @@ def test_get_indicators(connected, use_to_html): sys.version_info < (3, 7), reason="AttributeError: 'Styler' object has no attribute 'to_html'", ) +@pytest.mark.skipif( + pd_style is None, + reason="Missing optional dependency 'Jinja2'. DataFrame.style requires jinja2.", +) def test_get_pandas_styler(connected, use_to_html): styler = get_pandas_styler() show(styler, connected=connected, use_to_html=use_to_html)