From fab0ea7648f351ded130b220e676b3d9934004a3 Mon Sep 17 00:00:00 2001 From: Maxime Liquet <35924738+maximlt@users.noreply.github.com> Date: Wed, 18 Oct 2023 18:56:39 +0200 Subject: [PATCH] handle patching with NaT values (#5675) --- panel/tests/widgets/test_tables.py | 23 +++++++++++++++++++++++ panel/widgets/tables.py | 5 ++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/panel/tests/widgets/test_tables.py b/panel/tests/widgets/test_tables.py index 9c6a230b43..a51ee980f9 100644 --- a/panel/tests/widgets/test_tables.py +++ b/panel/tests/widgets/test_tables.py @@ -18,6 +18,7 @@ from panel.io.state import set_curdoc from panel.models.tabulator import CellClickEvent, TableEditEvent from panel.tests.util import serve_and_request, wait_until +from panel.util import BOKEH_JS_NAT from panel.widgets import Button, TextInput from panel.widgets.tables import DataFrame, Tabulator @@ -1295,6 +1296,28 @@ def test_tabulator_patch_with_timestamp(document, comm): if col != 'index': np.testing.assert_array_equal(table.value[col].values, expected[col]) +def test_tabulator_patch_with_NaT(document, comm): + df = pd.DataFrame(dict(A=pd.to_datetime(['1980-01-01', np.nan]))) + assert df.loc[1, 'A'] is pd.NaT + table = Tabulator(df) + + model = table.get_root(document, comm) + + table.patch({'A': [(0, pd.NaT)]}) + + # We're also checking that the NaT value that was in the original table + # at .loc[1, 'A'] is converted in the model as BOKEH_JS_NAT. + expected = { + 'index': np.array([0, 1]), + 'A': np.array([BOKEH_JS_NAT, BOKEH_JS_NAT]) + } + for col, values in model.source.data.items(): + expected_array = expected[col] + np.testing.assert_array_equal(values, expected_array) + # Not checking that the data in table.value is the same as expected + # In table.value we have NaT values, in expected the BOKEH_JS_NAT constant. + + def test_tabulator_stream_series_paginated_not_follow(document, comm): df = makeMixedDataFrame() table = Tabulator(df, pagination='remote', page_size=2) diff --git a/panel/widgets/tables.py b/panel/widgets/tables.py index 1681b94329..0031e260c0 100644 --- a/panel/widgets/tables.py +++ b/panel/widgets/tables.py @@ -29,7 +29,8 @@ from ..io.state import state from ..reactive import Reactive, ReactiveData from ..util import ( - clone_model, datetime_as_utctimestamp, isdatetime, lazy_load, updating, + BOKEH_JS_NAT, clone_model, datetime_as_utctimestamp, isdatetime, lazy_load, + updating, ) from .base import Widget from .button import Button @@ -824,6 +825,8 @@ def patch(self, patch_value, as_index=True): self.value.iloc[data_ind, columns.index(k)] = value if isinstance(value, pd.Timestamp): value = datetime_as_utctimestamp(value) + elif value is pd.NaT: + value = BOKEH_JS_NAT values.append((patch_ind, value)) patches[k] = values self._patch(patches)