From abfaa2729497b4a8251a712d7ffee1e630bd1e1b Mon Sep 17 00:00:00 2001 From: no author <> Date: Sun, 23 Jul 2023 11:59:59 -0400 Subject: [PATCH] Apply lint to perspective tests --- .../perspective/perspective/tests/__init__.py | 1 - .../perspective/tests/client_mode/__init__.py | 1 - .../tests/client_mode/test_client_mode.py | 52 +- .../perspective/perspective/tests/conftest.py | 16 +- .../perspective/tests/core/__init__.py | 1 - .../perspective/tests/core/test_aggregates.py | 81 +- .../perspective/tests/core/test_async.py | 4 +- .../perspective/tests/core/test_layout.py | 15 +- .../perspective/tests/core/test_plugin.py | 6 +- .../perspective/tests/core/test_sort.py | 4 +- .../perspective/tests/core/test_threadpool.py | 12 +- .../perspective/tests/handlers/__init__.py | 1 - .../tests/handlers/test_aiohttp_async_mode.py | 4 +- .../tests/handlers/test_aiohttp_handler.py | 20 +- .../handlers/test_aiohttp_handler_chunked.py | 20 +- .../tests/handlers/test_aiohttp_lock.py | 4 +- .../test_starlette_handler_chunked.py | 4 +- .../tests/handlers/test_starlette_lock.py | 4 +- .../tests/handlers/test_tornado_async_mode.py | 4 +- .../tests/handlers/test_tornado_handler.py | 28 +- .../handlers/test_tornado_handler_chunked.py | 12 +- .../tests/handlers/test_tornado_lock.py | 4 +- .../test_tornado_thread_pool_executor.py | 4 +- .../perspective/tests/manager/__init__.py | 1 - .../perspective/tests/manager/test_manager.py | 8 +- .../perspective/tests/manager/test_session.py | 27 +- .../perspective/tests/table/__init__.py | 1 - .../tests/table/object_sequence.py | 17 +- .../perspective/tests/table/test_delete.py | 2 +- .../perspective/tests/table/test_exception.py | 20 +- .../perspective/tests/table/test_leaks.py | 5 +- .../perspective/tests/table/test_ports.py | 25 +- .../perspective/tests/table/test_table.py | 348 +---- .../tests/table/test_table_arrow.py | 387 ++--- .../tests/table/test_table_datetime.py | 1308 +++-------------- .../tests/table/test_table_infer.py | 31 +- .../tests/table/test_table_limit.py | 9 +- .../tests/table/test_table_numpy.py | 764 +++------- .../tests/table/test_table_pandas.py | 609 ++------ .../perspective/tests/table/test_to_arrow.py | 359 +---- .../perspective/tests/table/test_to_format.py | 524 ++----- .../perspective/tests/table/test_update.py | 240 +-- .../tests/table/test_update_arrow.py | 815 +++------- .../tests/table/test_update_numpy.py | 265 +--- .../tests/table/test_update_pandas.py | 189 +-- .../perspective/tests/table/test_view.py | 960 +++--------- .../tests/table/test_view_expression.py | 580 +++----- .../perspective/tests/viewer/__init__.py | 1 - .../perspective/tests/viewer/test_validate.py | 1 - .../perspective/tests/viewer/test_viewer.py | 52 +- .../perspective/tests/widget/__init__.py | 1 - .../perspective/tests/widget/test_widget.py | 106 +- .../tests/widget/test_widget_pandas.py | 222 ++- python/perspective/pyproject.toml | 5 - python/perspective/setup.cfg | 1 - tools/perspective-scripts/fix_python.mjs | 2 +- 56 files changed, 1971 insertions(+), 6216 deletions(-) diff --git a/python/perspective/perspective/tests/__init__.py b/python/perspective/perspective/tests/__init__.py index 08a51ceca3..284e70816f 100644 --- a/python/perspective/perspective/tests/__init__.py +++ b/python/perspective/perspective/tests/__init__.py @@ -9,4 +9,3 @@ # ┃ This file is part of the Perspective library, distributed under the terms ┃ # ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - diff --git a/python/perspective/perspective/tests/client_mode/__init__.py b/python/perspective/perspective/tests/client_mode/__init__.py index 08a51ceca3..284e70816f 100644 --- a/python/perspective/perspective/tests/client_mode/__init__.py +++ b/python/perspective/perspective/tests/client_mode/__init__.py @@ -9,4 +9,3 @@ # ┃ This file is part of the Perspective library, distributed under the terms ┃ # ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - diff --git a/python/perspective/perspective/tests/client_mode/test_client_mode.py b/python/perspective/perspective/tests/client_mode/test_client_mode.py index 6cb2c5c211..0cad98375b 100644 --- a/python/perspective/perspective/tests/client_mode/test_client_mode.py +++ b/python/perspective/perspective/tests/client_mode/test_client_mode.py @@ -141,11 +141,7 @@ def test_widget_client_np_date(self, rename_libraries): import perspective assert perspective.is_libpsp() is False - data = { - "a": np.array( - [date(2020, i, 1) for i in range(1, 13)], dtype="datetime64[D]" - ) - } + data = {"a": np.array([date(2020, i, 1) for i in range(1, 13)], dtype="datetime64[D]")} widget = perspective.PerspectiveWidget(data) assert hasattr(widget, "table") is False assert widget._data == {"a": ["2020-{:02d}-01".format(i) for i in range(1, 13)]} @@ -163,9 +159,7 @@ def test_widget_client_df_date(self, rename_libraries): import perspective assert perspective.is_libpsp() is False - data = pd.DataFrame( - {"a": [date(2020, i, 1) for i in range(1, 13)]}, dtype="datetime64[ns]" - ) + data = pd.DataFrame({"a": [date(2020, i, 1) for i in range(1, 13)]}, dtype="datetime64[ns]") widget = perspective.PerspectiveWidget(data) assert hasattr(widget, "table") is False assert widget._data == { @@ -177,9 +171,7 @@ def test_widget_client_df_date_object(self, rename_libraries): import perspective assert perspective.is_libpsp() is False - data = pd.DataFrame( - {"a": [date(2020, i, 1) for i in range(1, 13)]}, dtype="object" - ) + data = pd.DataFrame({"a": [date(2020, i, 1) for i in range(1, 13)]}, dtype="object") widget = perspective.PerspectiveWidget(data) assert hasattr(widget, "table") is False assert widget._data == { @@ -194,9 +186,7 @@ def test_widget_client_datetime(self, rename_libraries): data = {"a": [datetime(2020, i, 1, 12, 30, 45) for i in range(1, 13)]} widget = perspective.PerspectiveWidget(data) assert hasattr(widget, "table") is False - assert widget._data == { - "a": ["2020-{:02d}-01 12:30:45".format(i) for i in range(1, 13)] - } + assert widget._data == {"a": ["2020-{:02d}-01 12:30:45".format(i) for i in range(1, 13)]} def test_widget_client_np_datetime(self, rename_libraries): import perspective @@ -210,24 +200,16 @@ def test_widget_client_np_datetime(self, rename_libraries): } widget = perspective.PerspectiveWidget(data) assert hasattr(widget, "table") is False - assert widget._data == { - "a": ["2020-{:02d}-01 12:30:45".format(i) for i in range(1, 13)] - } + assert widget._data == {"a": ["2020-{:02d}-01 12:30:45".format(i) for i in range(1, 13)]} def test_widget_client_np_datetime_object(self, rename_libraries): import perspective assert perspective.is_libpsp() is False - data = { - "a": np.array( - [datetime(2020, i, 1, 12, 30, 45) for i in range(1, 13)], dtype="object" - ) - } + data = {"a": np.array([datetime(2020, i, 1, 12, 30, 45) for i in range(1, 13)], dtype="object")} widget = perspective.PerspectiveWidget(data) assert hasattr(widget, "table") is False - assert widget._data == { - "a": ["2020-{:02d}-01 12:30:45".format(i) for i in range(1, 13)] - } + assert widget._data == {"a": ["2020-{:02d}-01 12:30:45".format(i) for i in range(1, 13)]} def test_widget_client_df_datetime(self, rename_libraries): import perspective @@ -272,9 +254,7 @@ def test_widget_client_np_recarray(self, rename_libraries): import perspective assert perspective.is_libpsp() is False - data = np.array([(1, 2), (3, 4)], dtype=[("a", "int64"), ("b", "int64")]).view( - np.recarray - ) + data = np.array([(1, 2), (3, 4)], dtype=[("a", "int64"), ("b", "int64")]).view(np.recarray) widget = perspective.PerspectiveWidget(data) assert hasattr(widget, "table") is False assert widget._data == {"a": [1, 3], "b": [2, 4]} @@ -355,9 +335,7 @@ def test_widget_client_schema(self, rename_libraries): import perspective assert perspective.is_libpsp() is False - widget = perspective.PerspectiveWidget( - {"a": int, "b": float, "c": bool, "d": date, "e": datetime, "f": str} - ) + widget = perspective.PerspectiveWidget({"a": int, "b": float, "c": bool, "d": date, "e": datetime, "f": str}) assert hasattr(widget, "table") is False assert widget._data == { "a": "integer", @@ -375,9 +353,7 @@ def test_widget_client_update(self, rename_libraries): data = {"a": np.arange(0, 50)} comparison_data = {"a": [i for i in range(50)]} widget = perspective.PerspectiveWidget(data) - mocked_post = partial( - mock_post, assert_msg={"cmd": "update", "data": comparison_data} - ) + mocked_post = partial(mock_post, assert_msg={"cmd": "update", "data": comparison_data}) widget.post = MethodType(mocked_post, widget) widget.update(data) assert hasattr(widget, "table") is False @@ -389,9 +365,7 @@ def test_widget_client_replace(self, rename_libraries): data = {"a": np.arange(0, 50)} new_data = {"a": [1]} widget = perspective.PerspectiveWidget(data) - mocked_post = partial( - mock_post, assert_msg={"cmd": "replace", "data": new_data} - ) + mocked_post = partial(mock_post, assert_msg={"cmd": "replace", "data": new_data}) widget.post = MethodType(mocked_post, widget) widget.replace(new_data) assert widget._data is new_data @@ -475,9 +449,7 @@ def test_widget_load_split_by_client(self, rename_libraries): ] tuples = list(zip(*arrays)) index = pd.MultiIndex.from_tuples(tuples, names=["first", "second", "third"]) - df_both = pd.DataFrame( - np.random.randn(3, 16), index=["A", "B", "C"], columns=index - ) + df_both = pd.DataFrame(np.random.randn(3, 16), index=["A", "B", "C"], columns=index) widget = perspective.PerspectiveWidget(df_both) assert hasattr(widget, "table") is False assert widget.columns == ["value"] diff --git a/python/perspective/perspective/tests/conftest.py b/python/perspective/perspective/tests/conftest.py index 8a89ae377b..ab4c812951 100644 --- a/python/perspective/perspective/tests/conftest.py +++ b/python/perspective/perspective/tests/conftest.py @@ -73,9 +73,7 @@ def make_arrow(names, data, types=None, legacy=False): batch = pa.RecordBatch.from_arrays(arrays, names) table = pa.Table.from_batches([batch]) - writer = pa.RecordBatchStreamWriter( - stream, table.schema, use_legacy_format=legacy - ) + writer = pa.RecordBatchStreamWriter(stream, table.schema, use_legacy_format=legacy) writer.write_table(table) writer.close() @@ -96,9 +94,7 @@ def make_arrow_from_pandas(df, schema=None, legacy=False): stream = pa.BufferOutputStream() table = pa.Table.from_pandas(df, schema=schema) - writer = pa.RecordBatchStreamWriter( - stream, table.schema, use_legacy_format=legacy - ) + writer = pa.RecordBatchStreamWriter(stream, table.schema, use_legacy_format=legacy) writer.write_table(table) writer.close() @@ -138,9 +134,7 @@ def make_dictionary_arrow(names, data, types=None, legacy=False): batch = pa.RecordBatch.from_arrays(arrays, names) table = pa.Table.from_batches([batch]) - writer = pa.RecordBatchStreamWriter( - stream, table.schema, use_legacy_format=legacy - ) + writer = pa.RecordBatchStreamWriter(stream, table.schema, use_legacy_format=legacy) writer.write_table(table) writer.close() @@ -220,9 +214,7 @@ def superstore(count=100): dat["Row ID"] = id dat["Order ID"] = "{}-{}".format(fake.ein(), fake.zipcode()) dat["Order Date"] = fake.date_this_year() - dat["Ship Date"] = fake.date_between_dates(dat["Order Date"]).strftime( - "%Y-%m-%d" - ) + dat["Ship Date"] = fake.date_between_dates(dat["Order Date"]).strftime("%Y-%m-%d") dat["Order Date"] = dat["Order Date"].strftime("%Y-%m-%d") dat["Ship Mode"] = choice(["First Class", "Standard Class", "Second Class"]) dat["Ship Mode"] = choice(["First Class", "Standard Class", "Second Class"]) diff --git a/python/perspective/perspective/tests/core/__init__.py b/python/perspective/perspective/tests/core/__init__.py index 08a51ceca3..284e70816f 100644 --- a/python/perspective/perspective/tests/core/__init__.py +++ b/python/perspective/perspective/tests/core/__init__.py @@ -9,4 +9,3 @@ # ┃ This file is part of the Perspective library, distributed under the terms ┃ # ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - diff --git a/python/perspective/perspective/tests/core/test_aggregates.py b/python/perspective/perspective/tests/core/test_aggregates.py index 955665955b..fa80bd11b8 100644 --- a/python/perspective/perspective/tests/core/test_aggregates.py +++ b/python/perspective/perspective/tests/core/test_aggregates.py @@ -11,26 +11,18 @@ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ from pytest import raises -from perspective import PerspectiveError, PerspectiveViewer,\ - PerspectiveWidget, Aggregate, Table +from perspective import PerspectiveError, PerspectiveViewer, PerspectiveWidget, Aggregate, Table class TestAggregates: - def test_aggregates_widget_load(self): - aggs = { - "a": Aggregate.AVG, - "b": Aggregate.LAST - } + aggs = {"a": Aggregate.AVG, "b": Aggregate.LAST} data = {"a": [1, 2, 3], "b": ["a", "b", "c"]} widget = PerspectiveWidget(data, aggregates=aggs) assert widget.aggregates == aggs def test_aggregates_widget_load_weighted_mean(self): - aggs = { - "a": Aggregate.AVG, - "b": ["weighted mean", "a"] - } + aggs = {"a": Aggregate.AVG, "b": ["weighted mean", "a"]} data = {"a": [1, 2, 3], "b": ["a", "b", "c"]} widget = PerspectiveWidget(data, aggregates=aggs) assert widget.aggregates == aggs @@ -38,14 +30,8 @@ def test_aggregates_widget_load_weighted_mean(self): def test_aggregates_widget_setattr(self): data = {"a": [1, 2, 3], "b": ["a", "b", "c"]} widget = PerspectiveWidget(data) - widget.aggregates = { - "a": Aggregate.ANY, - "b": Aggregate.LAST - } - assert widget.aggregates == { - "a": "any", - "b": "last" - } + widget.aggregates = {"a": Aggregate.ANY, "b": Aggregate.LAST} + assert widget.aggregates == {"a": "any", "b": "last"} def test_aggregates_widget_load_invalid(self): data = {"a": [1, 2, 3], "b": ["a", "b", "c"]} @@ -92,45 +78,42 @@ def test_aggregates_viewer_set_all(self): assert viewer.aggregates == {"a": agg.value} def get_median(self, input_data): - table = Table(data=input_data) - view = table.view( - columns=['Price'], - aggregates={'Price':'median'}, - group_by=['Item']) + table = Table(data=input_data) + view = table.view(columns=["Price"], aggregates={"Price": "median"}, group_by=["Item"]) - return view.to_json()[0]['Price'] + return view.to_json()[0]["Price"] def test_aggregate_median(self): numeric_data = [ - {'Item':'Book','Price':2.0}, - {'Item':'Book','Price':3.0}, - {'Item':'Book','Price':5.0}, - {'Item':'Book','Price':4.0}, - {'Item':'Book','Price':8.0}, - {'Item':'Book','Price':9.0}, - {'Item':'Book','Price':6.0}, + {"Item": "Book", "Price": 2.0}, + {"Item": "Book", "Price": 3.0}, + {"Item": "Book", "Price": 5.0}, + {"Item": "Book", "Price": 4.0}, + {"Item": "Book", "Price": 8.0}, + {"Item": "Book", "Price": 9.0}, + {"Item": "Book", "Price": 6.0}, ] non_numeric_data = [ - {'Item':'Book','Price':'2'}, - {'Item':'Book','Price':'3'}, - {'Item':'Book','Price':'5'}, - {'Item':'Book','Price':'4'}, - {'Item':'Book','Price':'8'}, - {'Item':'Book','Price':'9'}, - {'Item':'Book','Price':'6'}, + {"Item": "Book", "Price": "2"}, + {"Item": "Book", "Price": "3"}, + {"Item": "Book", "Price": "5"}, + {"Item": "Book", "Price": "4"}, + {"Item": "Book", "Price": "8"}, + {"Item": "Book", "Price": "9"}, + {"Item": "Book", "Price": "6"}, ] # Testing with numeric data - assert self.get_median(numeric_data) == 5.0 #List = [2.0,3.0,5.0,4.0,8.0,9.0,6.0], median = 5.0 - assert self.get_median(numeric_data[:2]) == 2.5 #List = [2.0,3.0], median = 2.5 - assert self.get_median(numeric_data[5:]) == 7.5 #List = [9.0,6.0], median = 7.5 - assert self.get_median(numeric_data[1:]) == 5.5 #List = [3.0,5.0,4.0,8.0,9.0,6.0], median = 5.5 - assert self.get_median(numeric_data[::2]) == 5.5 #List = [2.0,5.0,8.0,6.0], median = 5.5 + assert self.get_median(numeric_data) == 5.0 # List = [2.0,3.0,5.0,4.0,8.0,9.0,6.0], median = 5.0 + assert self.get_median(numeric_data[:2]) == 2.5 # List = [2.0,3.0], median = 2.5 + assert self.get_median(numeric_data[5:]) == 7.5 # List = [9.0,6.0], median = 7.5 + assert self.get_median(numeric_data[1:]) == 5.5 # List = [3.0,5.0,4.0,8.0,9.0,6.0], median = 5.5 + assert self.get_median(numeric_data[::2]) == 5.5 # List = [2.0,5.0,8.0,6.0], median = 5.5 # Testing with non-numeric data - assert self.get_median(non_numeric_data) == '5' #List = ['2','3','5','4','8','9','6'], median = '5' - assert self.get_median(non_numeric_data[:2]) == '3' #List = ['2','3'], median = '5' - assert self.get_median(non_numeric_data[5:]) == '9' #List = ['9','6'], median = '9' - assert self.get_median(non_numeric_data[1:]) == '6' #List = ['3','5','4','8','9','6'], median = '6' - assert self.get_median(non_numeric_data[::2]) == '6' #List = ['2','5','8','6'], median = '6' \ No newline at end of file + assert self.get_median(non_numeric_data) == "5" # List = ['2','3','5','4','8','9','6'], median = '5' + assert self.get_median(non_numeric_data[:2]) == "3" # List = ['2','3'], median = '5' + assert self.get_median(non_numeric_data[5:]) == "9" # List = ['9','6'], median = '9' + assert self.get_median(non_numeric_data[1:]) == "6" # List = ['3','5','4','8','9','6'], median = '6' + assert self.get_median(non_numeric_data[::2]) == "6" # List = ['2','5','8','6'], median = '6' diff --git a/python/perspective/perspective/tests/core/test_async.py b/python/perspective/perspective/tests/core/test_async.py index 027ca5c411..53f5454aac 100644 --- a/python/perspective/perspective/tests/core/test_async.py +++ b/python/perspective/perspective/tests/core/test_async.py @@ -226,9 +226,7 @@ def _counter(key, f, *args, **kwargs): return f(*args, **kwargs) short_delay_queue_process = partial(_counter, "sync") - long_delay_queue_process = partial( - TestAsync.loop.add_timeout, 1, _counter, "async" - ) + long_delay_queue_process = partial(TestAsync.loop.add_timeout, 1, _counter, "async") tbl = Table({"a": int, "b": float, "c": str}) tbl2 = Table({"a": int, "b": float, "c": str}) diff --git a/python/perspective/perspective/tests/core/test_layout.py b/python/perspective/perspective/tests/core/test_layout.py index 079b046ffa..9f4fcac8de 100644 --- a/python/perspective/perspective/tests/core/test_layout.py +++ b/python/perspective/perspective/tests/core/test_layout.py @@ -16,14 +16,13 @@ class TestLayout: - def test_layout_invalid_plugin(self): - with patch('IPython.display.display'): - df = pd.DataFrame([1, 2], columns=['1']) + with patch("IPython.display.display"): + df = pd.DataFrame([1, 2], columns=["1"]) PerspectiveWidget(df, plugin=Plugin.YBAR) - PerspectiveWidget(df, plugin='Y Line') + PerspectiveWidget(df, plugin="Y Line") try: - PerspectiveWidget(df, plugin='test') + PerspectiveWidget(df, plugin="test") assert False except PerspectiveError: pass @@ -35,9 +34,9 @@ def test_layout_invalid_plugin(self): pass def test_layout_invalid_columns(self): - with patch('IPython.display.display'): - df = pd.DataFrame([1, 2], columns=['1']) - PerspectiveWidget(df, plugin=Plugin.YBAR, columns=['1']) + with patch("IPython.display.display"): + df = pd.DataFrame([1, 2], columns=["1"]) + PerspectiveWidget(df, plugin=Plugin.YBAR, columns=["1"]) try: PerspectiveWidget(df, plugin=Plugin.YBAR, columns=5) assert False diff --git a/python/perspective/perspective/tests/core/test_plugin.py b/python/perspective/perspective/tests/core/test_plugin.py index c954dbab5d..bbfde03806 100644 --- a/python/perspective/perspective/tests/core/test_plugin.py +++ b/python/perspective/perspective/tests/core/test_plugin.py @@ -11,12 +11,10 @@ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ from pytest import raises -from perspective import PerspectiveError, PerspectiveViewer,\ - PerspectiveWidget, Plugin +from perspective import PerspectiveError, PerspectiveViewer, PerspectiveWidget, Plugin class TestPlugin: - def test_plugin_widget_load_grid(self): data = {"a": [1, 2, 3], "b": ["a", "b", "c"]} widget = PerspectiveWidget(data, plugin=Plugin.GRID) @@ -40,7 +38,7 @@ def test_plugin_widget_load_invalid(self): def test_plugin_widget_setattr_invalid(self): data = {"a": [1, 2, 3], "b": ["a", "b", "c"]} - widget = PerspectiveWidget(data) + widget = PerspectiveWidget(data) with raises(PerspectiveError): widget.plugin = "?" diff --git a/python/perspective/perspective/tests/core/test_sort.py b/python/perspective/perspective/tests/core/test_sort.py index eeea5afb2a..6025d5b032 100644 --- a/python/perspective/perspective/tests/core/test_sort.py +++ b/python/perspective/perspective/tests/core/test_sort.py @@ -11,12 +11,10 @@ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ from pytest import raises -from perspective import PerspectiveError, PerspectiveViewer,\ - PerspectiveWidget, Sort +from perspective import PerspectiveError, PerspectiveViewer, PerspectiveWidget, Sort class TestSort(object): - def test_sort_widget_load(self): data = {"a": [1, 2, 3], "b": ["a", "b", "c"]} widget = PerspectiveWidget(data, sort=[["a", Sort.DESC]]) diff --git a/python/perspective/perspective/tests/core/test_threadpool.py b/python/perspective/perspective/tests/core/test_threadpool.py index dcc824eb86..0d36e9648e 100644 --- a/python/perspective/perspective/tests/core/test_threadpool.py +++ b/python/perspective/perspective/tests/core/test_threadpool.py @@ -12,11 +12,13 @@ from perspective import Table, set_threadpool_size + def compare_delta(received, expected): """Compare an arrow-serialized row delta by constructing a Table.""" tbl = Table(received) assert tbl.view().to_dict() == expected + class TestThreadpool(object): def test_set_threadpool_size(self): set_threadpool_size(1) @@ -25,10 +27,7 @@ def test_set_threadpool_size(self): view = tbl.view() assert view.num_rows() == 2 assert view.num_columns() == 2 - assert view.schema() == { - "a": int, - "b": int - } + assert view.schema() == {"a": int, "b": int} assert view.to_records() == data def test_set_threadpool_size_max(self): @@ -38,8 +37,5 @@ def test_set_threadpool_size_max(self): view = tbl.view() assert view.num_rows() == 2 assert view.num_columns() == 2 - assert view.schema() == { - "a": int, - "b": int - } + assert view.schema() == {"a": int, "b": int} assert view.to_records() == data diff --git a/python/perspective/perspective/tests/handlers/__init__.py b/python/perspective/perspective/tests/handlers/__init__.py index 08a51ceca3..284e70816f 100644 --- a/python/perspective/perspective/tests/handlers/__init__.py +++ b/python/perspective/perspective/tests/handlers/__init__.py @@ -9,4 +9,3 @@ # ┃ This file is part of the Perspective library, distributed under the terms ┃ # ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - diff --git a/python/perspective/perspective/tests/handlers/test_aiohttp_async_mode.py b/python/perspective/perspective/tests/handlers/test_aiohttp_async_mode.py index b7a6526697..6b19404b91 100644 --- a/python/perspective/perspective/tests/handlers/test_aiohttp_async_mode.py +++ b/python/perspective/perspective/tests/handlers/test_aiohttp_async_mode.py @@ -67,9 +67,7 @@ def setup_method(self): async def websocket_client(self, app, aiohttp_client): client = await aiohttp_client(app) - return await websocket( - "http://{}:{}/websocket".format(client.host, client.port), client.session - ) + return await websocket("http://{}:{}/websocket".format(client.host, client.port), client.session) @pytest.mark.asyncio async def test_aiohttp_handler_async_manager_thread(self, app, aiohttp_client): diff --git a/python/perspective/perspective/tests/handlers/test_aiohttp_handler.py b/python/perspective/perspective/tests/handlers/test_aiohttp_handler.py index 178e49cf15..75701607a0 100644 --- a/python/perspective/perspective/tests/handlers/test_aiohttp_handler.py +++ b/python/perspective/perspective/tests/handlers/test_aiohttp_handler.py @@ -60,9 +60,7 @@ async def websocket_client(self, app, aiohttp_client): Perspective aiottp server. """ client = await aiohttp_client(app) - return await websocket( - "http://{}:{}/websocket".format(client.host, client.port), client.session - ) + return await websocket("http://{}:{}/websocket".format(client.host, client.port), client.session) @pytest.mark.asyncio async def test_aiohttp_handler_init_terminate(self, app, aiohttp_client): @@ -123,9 +121,7 @@ async def test_aiohttp_handler_table_update(self, app, aiohttp_client): assert size2 == 20 @pytest.mark.asyncio - async def test_aiohttp_handler_table_update_port( - self, app, aiohttp_client, sentinel - ): + async def test_aiohttp_handler_table_update_port(self, app, aiohttp_client, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -158,9 +154,7 @@ def updater(port_id): assert s.get() is True @pytest.mark.asyncio - async def test_aiohttp_handler_table_update_row_delta( - self, app, aiohttp_client, sentinel - ): + async def test_aiohttp_handler_table_update_row_delta(self, app, aiohttp_client, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -190,9 +184,7 @@ def updater(port_id, delta): assert s.get() is True @pytest.mark.asyncio - async def test_aiohttp_handler_table_update_row_delta_port( - self, app, aiohttp_client, sentinel - ): + async def test_aiohttp_handler_table_update_row_delta_port(self, app, aiohttp_client, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -289,9 +281,7 @@ async def test_aiohttp_handler_create_view_to_arrow(self, app, aiohttp_client): assert Table(output).schema(as_string=True) == expected @pytest.mark.asyncio - async def test_aiohttp_handler_create_view_to_arrow_update( - self, app, aiohttp_client - ): + async def test_aiohttp_handler_create_view_to_arrow_update(self, app, aiohttp_client): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) diff --git a/python/perspective/perspective/tests/handlers/test_aiohttp_handler_chunked.py b/python/perspective/perspective/tests/handlers/test_aiohttp_handler_chunked.py index 64a87f003a..c4697cdd68 100644 --- a/python/perspective/perspective/tests/handlers/test_aiohttp_handler_chunked.py +++ b/python/perspective/perspective/tests/handlers/test_aiohttp_handler_chunked.py @@ -37,9 +37,7 @@ async def websocket_handler(request): - handler = PerspectiveAIOHTTPHandler( - manager=MANAGER, request=request, chunk_size=500 - ) + handler = PerspectiveAIOHTTPHandler(manager=MANAGER, request=request, chunk_size=500) await handler.run() @@ -61,14 +59,10 @@ async def websocket_client(self, app, aiohttp_client): Perspective aiottp server. """ client = await aiohttp_client(app) - return await websocket( - "http://{}:{}/websocket".format(client.host, client.port), client.session - ) + return await websocket("http://{}:{}/websocket".format(client.host, client.port), client.session) @pytest.mark.asyncio - async def test_aiohttp_handler_create_view_to_arrow_chunked( - self, app, aiohttp_client - ): + async def test_aiohttp_handler_create_view_to_arrow_chunked(self, app, aiohttp_client): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -82,9 +76,7 @@ async def test_aiohttp_handler_create_view_to_arrow_chunked( assert Table(output).schema(as_string=True) == expected @pytest.mark.asyncio - async def test_aiohttp_handler_create_view_to_arrow_update_chunked( - self, app, aiohttp_client - ): + async def test_aiohttp_handler_create_view_to_arrow_update_chunked(self, app, aiohttp_client): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -102,9 +94,7 @@ async def test_aiohttp_handler_create_view_to_arrow_update_chunked( assert size2 == 110 @pytest.mark.asyncio - async def test_aiohttp_handler_update_chunked_interleaved_with_trivial( - self, app, aiohttp_client - ): + async def test_aiohttp_handler_update_chunked_interleaved_with_trivial(self, app, aiohttp_client): """Tests that, when a chunked response `output_fut` is interleaved with a response belonging to another message ID (and not binary encoded) `size3`, both messages de-multiplex correclty and succeed. diff --git a/python/perspective/perspective/tests/handlers/test_aiohttp_lock.py b/python/perspective/perspective/tests/handlers/test_aiohttp_lock.py index 5790667f1c..3fdb224097 100644 --- a/python/perspective/perspective/tests/handlers/test_aiohttp_lock.py +++ b/python/perspective/perspective/tests/handlers/test_aiohttp_lock.py @@ -59,9 +59,7 @@ async def websocket_client(self, app, aiohttp_client): Perspective aiottp server. """ client = await aiohttp_client(app) - return await websocket( - "http://{}:{}/websocket".format(client.host, client.port), client.session - ) + return await websocket("http://{}:{}/websocket".format(client.host, client.port), client.session) @pytest.mark.asyncio async def test_aiohttp_handler_lock_inflight(self, app, aiohttp_client): diff --git a/python/perspective/perspective/tests/handlers/test_starlette_handler_chunked.py b/python/perspective/perspective/tests/handlers/test_starlette_handler_chunked.py index 012870a451..052313d848 100644 --- a/python/perspective/perspective/tests/handlers/test_starlette_handler_chunked.py +++ b/python/perspective/perspective/tests/handlers/test_starlette_handler_chunked.py @@ -41,9 +41,7 @@ async def websocket_handler(websocket: WebSocket): - handler = PerspectiveStarletteHandler( - manager=MANAGER, websocket=websocket, chunk_size=500 - ) + handler = PerspectiveStarletteHandler(manager=MANAGER, websocket=websocket, chunk_size=500) await handler.run() diff --git a/python/perspective/perspective/tests/handlers/test_starlette_lock.py b/python/perspective/perspective/tests/handlers/test_starlette_lock.py index 5854817976..943012b81b 100644 --- a/python/perspective/perspective/tests/handlers/test_starlette_lock.py +++ b/python/perspective/perspective/tests/handlers/test_starlette_lock.py @@ -40,9 +40,7 @@ async def websocket_handler(websocket: WebSocket): - handler = PerspectiveStarletteHandler( - manager=MANAGER, websocket=websocket, chunk_size=500 - ) + handler = PerspectiveStarletteHandler(manager=MANAGER, websocket=websocket, chunk_size=500) await handler.run() diff --git a/python/perspective/perspective/tests/handlers/test_tornado_async_mode.py b/python/perspective/perspective/tests/handlers/test_tornado_async_mode.py index 5abdf24e88..c5fce6c712 100644 --- a/python/perspective/perspective/tests/handlers/test_tornado_async_mode.py +++ b/python/perspective/perspective/tests/handlers/test_tornado_async_mode.py @@ -98,9 +98,7 @@ async def websocket_client(self, port): return client @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_async_manager_thread( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_async_manager_thread(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) diff --git a/python/perspective/perspective/tests/handlers/test_tornado_handler.py b/python/perspective/perspective/tests/handlers/test_tornado_handler.py index 4ec86eacc8..3ba97a461c 100644 --- a/python/perspective/perspective/tests/handlers/test_tornado_handler.py +++ b/python/perspective/perspective/tests/handlers/test_tornado_handler.py @@ -125,9 +125,7 @@ async def test_tornado_handler_table_update(self, app, http_client, http_port): assert size2 == 20 @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_table_update_port( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_table_update_port(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -160,9 +158,7 @@ def updater(port_id): assert s.get() is True @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_table_update_row_delta( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_table_update_row_delta(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -192,9 +188,7 @@ def updater(port_id, delta): assert s.get() is True @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_table_update_row_delta_port( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_table_update_row_delta_port(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -248,9 +242,7 @@ async def test_tornado_handler_table_remove(self, app, http_client, http_port): assert output == {"a": [i for i in range(5, 10)]} @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_create_view( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_create_view(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -265,9 +257,7 @@ async def test_tornado_handler_create_view( } @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_create_view_errors( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_create_view_errors(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -281,9 +271,7 @@ async def test_tornado_handler_create_view_errors( assert str(exc.value) == "Invalid column 'abcde' found in View columns.\n" @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_create_view_to_arrow( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_create_view_to_arrow(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -297,9 +285,7 @@ async def test_tornado_handler_create_view_to_arrow( assert Table(output).schema(as_string=True) == expected @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_create_view_to_arrow_update( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_create_view_to_arrow_update(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) diff --git a/python/perspective/perspective/tests/handlers/test_tornado_handler_chunked.py b/python/perspective/perspective/tests/handlers/test_tornado_handler_chunked.py index 71dd0bf170..5e732e4ea6 100644 --- a/python/perspective/perspective/tests/handlers/test_tornado_handler_chunked.py +++ b/python/perspective/perspective/tests/handlers/test_tornado_handler_chunked.py @@ -64,9 +64,7 @@ async def websocket_client(self, port): return client @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_create_view_to_arrow_chunked( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_create_view_to_arrow_chunked(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -80,9 +78,7 @@ async def test_tornado_handler_create_view_to_arrow_chunked( assert Table(output).schema(as_string=True) == expected @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_create_view_to_arrow_update_chunked( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_create_view_to_arrow_update_chunked(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) @@ -100,9 +96,7 @@ async def test_tornado_handler_create_view_to_arrow_update_chunked( assert size2 == 110 @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_update_chunked_interleaved_with_trivial( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_update_chunked_interleaved_with_trivial(self, app, http_client, http_port, sentinel): """Tests that, when a chunked response `output_fut` is interleaved with a response belonging to another message ID (and not binary encoded) `size3`, both messages de-multiplex correclty and succeed. diff --git a/python/perspective/perspective/tests/handlers/test_tornado_lock.py b/python/perspective/perspective/tests/handlers/test_tornado_lock.py index 2e722a3f39..64b7bb668d 100644 --- a/python/perspective/perspective/tests/handlers/test_tornado_lock.py +++ b/python/perspective/perspective/tests/handlers/test_tornado_lock.py @@ -83,9 +83,7 @@ async def websocket_client(self, port): return client @pytest.mark.gen_test(run_sync=False) - async def test_tornado_handler_lock_inflight( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_lock_inflight(self, app, http_client, http_port, sentinel): table_name = str(random.random()) _table = Table(data) MANAGER.host_table(table_name, _table) diff --git a/python/perspective/perspective/tests/handlers/test_tornado_thread_pool_executor.py b/python/perspective/perspective/tests/handlers/test_tornado_thread_pool_executor.py index 0cc1add407..33f814cda9 100644 --- a/python/perspective/perspective/tests/handlers/test_tornado_thread_pool_executor.py +++ b/python/perspective/perspective/tests/handlers/test_tornado_thread_pool_executor.py @@ -97,9 +97,7 @@ async def websocket_client(self, port): return client @pytest.mark.gen_test(run_sync=False, timeout=30) - async def test_tornado_handler_async_manager_thread( - self, app, http_client, http_port, sentinel - ): + async def test_tornado_handler_async_manager_thread(self, app, http_client, http_port, sentinel): global data table_name = str(random.random()) _table = Table(data) diff --git a/python/perspective/perspective/tests/manager/__init__.py b/python/perspective/perspective/tests/manager/__init__.py index 08a51ceca3..284e70816f 100644 --- a/python/perspective/perspective/tests/manager/__init__.py +++ b/python/perspective/perspective/tests/manager/__init__.py @@ -9,4 +9,3 @@ # ┃ This file is part of the Perspective library, distributed under the terms ┃ # ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - diff --git a/python/perspective/perspective/tests/manager/test_manager.py b/python/perspective/perspective/tests/manager/test_manager.py index 1f5b675e02..dddccfdd46 100644 --- a/python/perspective/perspective/tests/manager/test_manager.py +++ b/python/perspective/perspective/tests/manager/test_manager.py @@ -464,9 +464,7 @@ def test_manager_table_validate_expressions(self): manager._process(message, post_callback) def test_manager_view_expression_schema(self): - post_callback = partial( - self.validate_post, expected={"id": 2, "data": {"abc": "float"}} - ) + post_callback = partial(self.validate_post, expected={"id": 2, "data": {"abc": "float"}}) make_view_message = { "id": 1, @@ -558,9 +556,7 @@ def handle_to_dict(msg): assert s.get() is True def test_manager_to_dict_with_nan(self, util, sentinel): - data = util.make_arrow( - ["a"], [[1.5, np.nan, 2.5, np.nan]], types=[pa.float64()] - ) + data = util.make_arrow(["a"], [[1.5, np.nan, 2.5, np.nan]], types=[pa.float64()]) s = sentinel(False) def handle_to_dict(msg): diff --git a/python/perspective/perspective/tests/manager/test_session.py b/python/perspective/perspective/tests/manager/test_session.py index 80a200e2f5..0c45b01fa3 100644 --- a/python/perspective/perspective/tests/manager/test_session.py +++ b/python/perspective/perspective/tests/manager/test_session.py @@ -19,7 +19,7 @@ class TestPerspectiveSession(object): def post(self, msg): - '''boilerplate callback to simulate a client's `post()` method.''' + """boilerplate callback to simulate a client's `post()` method.""" msg = json.loads(msg) assert msg["id"] is not None @@ -66,10 +66,7 @@ def handle_to_dict(msg): message = json.loads(msg) - assert message["data"] == { - "a": [1, 2, 3, 1, 2, 3], - "b": ["a", "b", "c", "str1", "str2", "str3"] - } + assert message["data"] == {"a": [1, 2, 3, 1, 2, 3], "b": ["a", "b", "c", "str1", "str2", "str3"]} manager = PerspectiveManager() sessions = [manager.new_session() for i in range(5)] @@ -127,9 +124,7 @@ def callback(updated): s.set(s.get() + 100) # simulate a client that holds callbacks by id - callbacks = { - 3: callback - } + callbacks = {3: callback} def post_update(msg): # when `on_update` is triggered, this callback gets the message @@ -138,9 +133,7 @@ def post_update(msg): assert message["id"] is not None if message["id"] == 3: # trigger callback - assert message["data"] == { - "port_id": 0 - } + assert message["data"] == {"port_id": 0} callbacks[message["id"]](message["data"]) # hook into the created view and pass it the callback @@ -194,9 +187,7 @@ def callback(updated): s.set(s.get() + 100) # simulate a client that holds callbacks by id - callbacks = { - 3: callback - } + callbacks = {3: callback} def post_update(msg): # when `on_update` is triggered, this callback gets the message @@ -205,9 +196,7 @@ def post_update(msg): assert message["id"] is not None if message["id"] == 3: # trigger callback - assert message["data"] == { - "port_id": 0 - } + assert message["data"] == {"port_id": 0} callbacks[message["id"]](message["data"]) # create a view and an on_update on each session @@ -243,8 +232,8 @@ def post_update(msg): assert "view" + str(random_session_id) not in manager._views.keys() assert len(manager._views.keys()) == 4 - + for callback in manager._callback_cache: assert callback["client_id"] != random_client_id - assert len(manager._callback_cache) == 4 \ No newline at end of file + assert len(manager._callback_cache) == 4 diff --git a/python/perspective/perspective/tests/table/__init__.py b/python/perspective/perspective/tests/table/__init__.py index 08a51ceca3..284e70816f 100644 --- a/python/perspective/perspective/tests/table/__init__.py +++ b/python/perspective/perspective/tests/table/__init__.py @@ -9,4 +9,3 @@ # ┃ This file is part of the Perspective library, distributed under the terms ┃ # ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - diff --git a/python/perspective/perspective/tests/table/object_sequence.py b/python/perspective/perspective/tests/table/object_sequence.py index 4daba2c69d..4f3bb860d1 100644 --- a/python/perspective/perspective/tests/table/object_sequence.py +++ b/python/perspective/perspective/tests/table/object_sequence.py @@ -26,7 +26,7 @@ def __int__(self): return int(self._value) def __repr__(self): - return 'test' if self._value == 1 else "test{}".format(self._value) + return "test" if self._value == 1 else "test{}".format(self._value) def run(): @@ -138,7 +138,6 @@ def run(): print(tbl.view().to_dict()["b"]) assert list(_ is not None for _ in tbl.view().to_dict()["b"]) == [True, True, False, True, False, True] - print() tbl.update([{"a": 1, "b": t2}]) # 1 for `t`, 1 for `data`, 1 for argument to sys.getrefcount, and 3 for the table @@ -254,9 +253,9 @@ def run2(): assert tbl.view().to_dict() == {"a": [0], "b": [t]} # seed a few to check - tbl.remove([1]) - tbl.remove([1]) - tbl.remove([1]) + tbl.remove([1]) + tbl.remove([1]) + tbl.remove([1]) for _ in range(10): pick = randint(1, 2) if indexes else 1 @@ -265,7 +264,7 @@ def run2(): while ind in indexes: ind = randint(1, 100) - print('adding', ind, 'refcount', t_ref_count, 'should be', sys.getrefcount(t)) + print("adding", ind, "refcount", t_ref_count, "should be", sys.getrefcount(t)) tbl.update({"a": [ind], "b": [t]}) t_ref_count += 1 indexes.add(ind) @@ -274,9 +273,9 @@ def run2(): else: ind = choice(list(indexes)) indexes.remove(ind) - tbl.remove([ind]) + tbl.remove([ind]) t_ref_count -= 1 - print('removing', ind, 'refcount', t_ref_count, 'should be', sys.getrefcount(t)) + print("removing", ind, "refcount", t_ref_count, "should be", sys.getrefcount(t)) assert sys.getrefcount(t) == t_ref_count print(t_ref_count) @@ -291,5 +290,3 @@ def run2(): # 1 for `t`, one for `data`, one for argument to sys.getrefcount print(sys.getrefcount(t), "should be", 2) assert sys.getrefcount(t) == 2 - - diff --git a/python/perspective/perspective/tests/table/test_delete.py b/python/perspective/perspective/tests/table/test_delete.py index 91f9d350ff..2636465c66 100644 --- a/python/perspective/perspective/tests/table/test_delete.py +++ b/python/perspective/perspective/tests/table/test_delete.py @@ -14,7 +14,6 @@ class TestDelete(object): - # delete def test_table_delete(self): @@ -28,6 +27,7 @@ def test_table_delete_callback(self, sentinel): def callback(): s.set(True) + data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) tbl.on_delete(callback) diff --git a/python/perspective/perspective/tests/table/test_exception.py b/python/perspective/perspective/tests/table/test_exception.py index ade62ad8f9..73c32f8bb6 100644 --- a/python/perspective/perspective/tests/table/test_exception.py +++ b/python/perspective/perspective/tests/table/test_exception.py @@ -22,10 +22,7 @@ def test_exception_from_core(self): # creating view with unknown column should throw tbl.view(group_by=["b"]) - assert ( - str(ex.value) - == "Invalid column 'b' found in View group_by.\n" - ) + assert str(ex.value) == "Invalid column 'b' found in View group_by.\n" def test_exception_from_core_catch_generic(self): tbl = Table({"a": [1, 2, 3]}) @@ -33,10 +30,7 @@ def test_exception_from_core_catch_generic(self): with raises(Exception) as ex: tbl.view(group_by=["b"]) - assert ( - str(ex.value) - == "Invalid column 'b' found in View group_by.\n" - ) + assert str(ex.value) == "Invalid column 'b' found in View group_by.\n" def test_exception_from_core_correct_types(self): tbl = Table({"a": [1, 2, 3]}) @@ -46,15 +40,9 @@ def test_exception_from_core_correct_types(self): tbl.view() tbl.delete() - assert ( - str(ex.value) - == "Cannot delete a Table with active views still linked to it - call delete() on each view, and try again." - ) + assert str(ex.value) == "Cannot delete a Table with active views still linked to it - call delete() on each view, and try again." with raises(PerspectiveCppError) as ex: tbl.view(group_by=["b"]) - assert ( - str(ex.value) - == "Invalid column 'b' found in View group_by.\n" - ) + assert str(ex.value) == "Invalid column 'b' found in View group_by.\n" diff --git a/python/perspective/perspective/tests/table/test_leaks.py b/python/perspective/perspective/tests/table/test_leaks.py index e876cca52b..7c0fe24ec2 100644 --- a/python/perspective/perspective/tests/table/test_leaks.py +++ b/python/perspective/perspective/tests/table/test_leaks.py @@ -16,7 +16,6 @@ class TestDelete(object): - # delete def test_table_delete(self): @@ -26,7 +25,7 @@ def test_table_delete(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) tbl.delete() - + mem2 = process.memory_info().rss # assert 1 < (max2 / max) < 1.01 @@ -41,7 +40,7 @@ def test_table_delete_with_view(self, sentinel): for x in range(10000): view = tbl.view() view.delete() - + tbl.delete() mem2 = process.memory_info().rss assert (mem2 - mem) < 2000000 diff --git a/python/perspective/perspective/tests/table/test_ports.py b/python/perspective/perspective/tests/table/test_ports.py index a6ea282640..cf29a002aa 100644 --- a/python/perspective/perspective/tests/table/test_ports.py +++ b/python/perspective/perspective/tests/table/test_ports.py @@ -13,15 +13,10 @@ import random from perspective.table import Table -data = { - "a": [1, 2, 3, 4], - "b": ["a", "b", "c", "d"], - "c": [True, False, True, False] -} +data = {"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"], "c": [True, False, True, False]} class TestPorts(object): - def test_make_port_sequential(self): table = Table(data) port_ids = [] @@ -41,20 +36,12 @@ def test_make_port_sequential_and_update(self): assert port_ids == list(range(1, 11)) for i in range(1, 11): - table.update({ - "a": [i], - "b": ["a"], - "c": [True] - }, port_id=i) + table.update({"a": [i], "b": ["a"], "c": [True]}, port_id=i) view = table.view() result = view.to_dict() - assert result == { - "a": [1, 2, 3, 4] + [i for i in range(1, 11)], - "b": ["a", "b", "c", "d"] + ["a" for i in range(10)], - "c": [True, False, True, False] + [True for i in range(10)] - } + assert result == {"a": [1, 2, 3, 4] + [i for i in range(1, 11)], "b": ["a", "b", "c", "d"] + ["a" for i in range(10)], "c": [True, False, True, False] + [True for i in range(10)]} def test_arbitary_port_updates(self): table = Table(data) @@ -71,11 +58,7 @@ def test_arbitary_port_updates(self): assert table.size() == 8 - assert table.view().to_dict() == { - "a": [1, 2, 3, 4] * 2, - "b": ["a", "b", "c", "d"] * 2, - "c": [True, False, True, False] * 2 - } + assert table.view().to_dict() == {"a": [1, 2, 3, 4] * 2, "b": ["a", "b", "c", "d"] * 2, "c": [True, False, True, False] * 2} def test_ports_should_only_notify_if_they_have_a_queued_update(self): table = Table(data) diff --git a/python/perspective/perspective/tests/table/test_table.py b/python/perspective/perspective/tests/table/test_table.py index 2d2033752b..991b59d14c 100644 --- a/python/perspective/perspective/tests/table/test_table.py +++ b/python/perspective/perspective/tests/table/test_table.py @@ -28,9 +28,7 @@ def test_empty_table(self): assert tbl.size() == 0 def test_table_not_iterable(self): - data = { - "a": 1 - } + data = {"a": 1} with raises(NotImplementedError): Table(data) @@ -43,92 +41,51 @@ def test_table_synchronous_process(self): def test_table_csv(self): data = "x,y,z\n1,a,true\n2,b,false\n3,c,true\n4,d,false" tbl = Table(data) - assert tbl.schema() == { - "x": int, - "y": str, - "z": bool - } + assert tbl.schema() == {"x": int, "y": str, "z": bool} view = tbl.view() - assert view.to_dict() == { - "x": [1, 2, 3, 4], - "y": ["a", "b", "c", "d"], - "z": [True, False, True, False] - } + assert view.to_dict() == {"x": [1, 2, 3, 4], "y": ["a", "b", "c", "d"], "z": [True, False, True, False]} def test_table_csv_with_nulls(self): tbl = Table("x,y\n1,") - assert tbl.schema() == { - "x": int, - "y": str - } + assert tbl.schema() == {"x": int, "y": str} view = tbl.view() - assert view.to_dict() == { - "x": [1], - "y": [None] - } + assert view.to_dict() == {"x": [1], "y": [None]} def test_table_csv_with_nulls_updated(self): tbl = Table("x,y\n1,", index="x") - assert tbl.schema() == { - "x": int, - "y": str - } + assert tbl.schema() == {"x": int, "y": str} view = tbl.view() - assert view.to_dict() == { - "x": [1], - "y": [None] - } + assert view.to_dict() == {"x": [1], "y": [None]} tbl.update("x,y\n1,abc\n2,123") - assert view.to_dict() == { - "x": [1, 2], - "y": ["abc", "123"] - } + assert view.to_dict() == {"x": [1, 2], "y": ["abc", "123"]} def test_table_correct_csv_nan_end(self): tbl = Table("str,int\n,1\n,2\nabc,3") - assert tbl.schema() == { - "str": str, - "int": int - } + assert tbl.schema() == {"str": str, "int": int} assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "str": ["", "", "abc"], - "int": [1, 2, 3] - } + assert tbl.view().to_dict() == {"str": ["", "", "abc"], "int": [1, 2, 3]} def test_table_correct_csv_nan_intermittent(self): tbl = Table("str,float\nabc,\n,2.5\nghi,") - assert tbl.schema() == { - "str": str, - "float": float - } + assert tbl.schema() == {"str": str, "float": float} assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "str": ["abc", "", "ghi"], - "float": [None, 2.5, None] - } + assert tbl.view().to_dict() == {"str": ["abc", "", "ghi"], "float": [None, 2.5, None]} def test_table_string_column_with_nulls_update_and_filter(self): - tbl = Table([{'a': '1', 'b': 2, 'c': '3'}, {'a': '2', 'b': 3, 'c': '4'}, {'a': '3', 'b': 3, 'c': None}], index='a') - view = tbl.view(filter=[['c', '==', '4']]) + tbl = Table([{"a": "1", "b": 2, "c": "3"}, {"a": "2", "b": 3, "c": "4"}, {"a": "3", "b": 3, "c": None}], index="a") + view = tbl.view(filter=[["c", "==", "4"]]) records = view.to_records() - tbl.update([{'a': '4', 'b': 10}]) + tbl.update([{"a": "4", "b": 10}]) assert records == view.to_records() def test_table_int(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": int, - "b": int - } + assert tbl.schema() == {"a": int, "b": int} def test_table_int_column_names(self): - data = { - "a": [1, 2, 3], - 0: [4, 5, 6] - } + data = {"a": [1, 2, 3], 0: [4, 5, 6]} with raises(PerspectiveError): Table(data) @@ -136,205 +93,109 @@ def test_table_nones(self): none_data = [{"a": 1, "b": None}, {"a": None, "b": 2}] tbl = Table(none_data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": int, - "b": int - } + assert tbl.schema() == {"a": int, "b": int} def test_table_bool(self): bool_data = [{"a": True, "b": False}, {"a": True, "b": True}] tbl = Table(bool_data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": bool, - "b": bool - } + assert tbl.schema() == {"a": bool, "b": bool} def test_table_bool_str(self): bool_data = [{"a": "True", "b": "False"}, {"a": "True", "b": "True"}] tbl = Table(bool_data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": bool, - "b": bool - } - assert tbl.view().to_dict() == { - "a": [True, True], - "b": [False, True] - } + assert tbl.schema() == {"a": bool, "b": bool} + assert tbl.view().to_dict() == {"a": [True, True], "b": [False, True]} def test_table_float(self): float_data = [{"a": 1.5, "b": 2.5}, {"a": 3.2, "b": 3.1}] tbl = Table(float_data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": float, - "b": float - } + assert tbl.schema() == {"a": float, "b": float} def test_table_str(self): str_data = [{"a": "b", "b": "b"}, {"a": "3", "b": "3"}] tbl = Table(str_data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": str, - "b": str - } + assert tbl.schema() == {"a": str, "b": str} def test_table_str_with_escape(self): - str_data = [{"a": "abc\"def\"", "b": "abc\"def\""}, {"a": 'abc\'def\'', "b": 'abc\'def\''}] + str_data = [{"a": 'abc"def"', "b": 'abc"def"'}, {"a": "abc'def'", "b": "abc'def'"}] tbl = Table(str_data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": str, - "b": str - } + assert tbl.schema() == {"a": str, "b": str} assert tbl.view().to_records() == str_data def test_table_str_unicode(self): str_data = [{"a": "ȀȁȀȃȀȁȀȃȀȁȀȃȀȁȀȃ", "b": "ЖДфйЖДфйЖДфйЖДфй"}] tbl = Table(str_data) assert tbl.size() == 1 - assert tbl.schema() == { - "a": str, - "b": str - } + assert tbl.schema() == {"a": str, "b": str} assert tbl.view().to_records() == str_data def test_table_date(self): str_data = [{"a": date.today(), "b": date.today()}] tbl = Table(str_data) assert tbl.size() == 1 - assert tbl.schema() == { - "a": date, - "b": date - } + assert tbl.schema() == {"a": date, "b": date} def test_table_datetime(self): str_data = [{"a": datetime.now(), "b": datetime.now()}] tbl = Table(str_data) assert tbl.size() == 1 - assert tbl.schema() == { - "a": datetime, - "b": datetime - } + assert tbl.schema() == {"a": datetime, "b": datetime} def test_table_columnar(self): data = {"a": [1, 2, 3], "b": [4, 5, 6]} tbl = Table(data) assert tbl.columns() == ["a", "b"] assert tbl.size() == 3 - assert tbl.schema() == { - "a": int, - "b": int - } + assert tbl.schema() == {"a": int, "b": int} def test_table_columnar_mixed_length(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.2}] tbl = Table(data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": float, - "b": float - } + assert tbl.schema() == {"a": float, "b": float} assert tbl.view().to_records() == [{"a": 1.5, "b": 2.5}, {"a": 3.2, "b": None}] # schema def test_table_schema(self): - data = {"a": int, - "b": float, - "c": str, - "d": bool, - "e": date, - "f": datetime} + data = {"a": int, "b": float, "c": str, "d": bool, "e": date, "f": datetime} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float, - "c": str, - "d": bool, - "e": date, - "f": datetime - } + assert tbl.schema() == {"a": int, "b": float, "c": str, "d": bool, "e": date, "f": datetime} def test_table_readable_string_schema(self): - data = {"a": "integer", - "b": "float", - "c": "string", - "d": "boolean", - "e": "date", - "f": "datetime"} + data = {"a": "integer", "b": "float", "c": "string", "d": "boolean", "e": "date", "f": "datetime"} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float, - "c": str, - "d": bool, - "e": date, - "f": datetime - } + assert tbl.schema() == {"a": int, "b": float, "c": str, "d": bool, "e": date, "f": datetime} def test_table_output_readable_schema(self): - data = {"a": "int32", - "b": "float64", - "c": "str", - "d": "bool", - "e": "date", - "f": "datetime"} + data = {"a": "int32", "b": "float64", "c": "str", "d": "bool", "e": "date", "f": "datetime"} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float, - "c": str, - "d": bool, - "e": date, - "f": datetime - } + assert tbl.schema() == {"a": int, "b": float, "c": str, "d": bool, "e": date, "f": datetime} def test_table_mixed_schema(self): - data = {"a": int, - "b": float, - "c": str, - "d": bool, - "e": date, - "f": datetime} + data = {"a": int, "b": float, "c": str, "d": bool, "e": date, "f": datetime} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float, - "c": str, - "d": bool, - "e": date, - "f": datetime - } + assert tbl.schema() == {"a": int, "b": float, "c": str, "d": bool, "e": date, "f": datetime} def test_table_output_string_schema(self): - data = {"a": int, - "b": float, - "c": str, - "d": bool, - "e": date, - "f": datetime} + data = {"a": int, "b": float, "c": str, "d": bool, "e": date, "f": datetime} tbl = Table(data) - assert tbl.schema(as_string=True) == { - "a": "integer", - "b": "float", - "c": "string", - "d": "boolean", - "e": "date", - "f": "datetime" - } + assert tbl.schema(as_string=True) == {"a": "integer", "b": "float", "c": "string", "d": "boolean", "e": "date", "f": "datetime"} def test_table_symmetric_schema(self): data = { @@ -343,20 +204,13 @@ def test_table_symmetric_schema(self): "c": ["a", "b", "c"], "d": [True, False, True], "e": [date.today(), date.today(), date.today()], - "f": [datetime.now(), datetime.now(), datetime.now()] + "f": [datetime.now(), datetime.now(), datetime.now()], } tbl = Table(data) schema = tbl.schema() - assert schema == { - "a": int, - "b": float, - "c": str, - "d": bool, - "e": date, - "f": datetime - } + assert schema == {"a": int, "b": float, "c": str, "d": bool, "e": date, "f": datetime} tbl2 = Table(schema) @@ -369,20 +223,13 @@ def test_table_symmetric_string_schema(self): "c": ["a", "b", "c"], "d": [True, False, True], "e": [date.today(), date.today(), date.today()], - "f": [datetime.now(), datetime.now(), datetime.now()] + "f": [datetime.now(), datetime.now(), datetime.now()], } tbl = Table(data) schema = tbl.schema(as_string=True) - assert schema == { - "a": "integer", - "b": "float", - "c": "string", - "d": "boolean", - "e": "date", - "f": "datetime" - } + assert schema == {"a": "integer", "b": "float", "c": "string", "d": "boolean", "e": "date", "f": "datetime"} tbl2 = Table(schema) @@ -416,44 +263,32 @@ def test_table_not_is_valid_filter_filter_op(self): def test_table_is_valid_filter_date(self): filter = ["a", t_filter_op.FILTER_OP_GT, date.today()] - tbl = Table({ - "a": date - }) + tbl = Table({"a": date}) assert tbl.is_valid_filter(filter) is True def test_table_not_is_valid_filter_date(self): filter = ["a", t_filter_op.FILTER_OP_GT, None] - tbl = Table({ - "a": date - }) + tbl = Table({"a": date}) assert tbl.is_valid_filter(filter) is False def test_table_is_valid_filter_datetime(self): filter = ["a", t_filter_op.FILTER_OP_GT, datetime.now()] - tbl = Table({ - "a": datetime - }) + tbl = Table({"a": datetime}) assert tbl.is_valid_filter(filter) is True def test_table_not_is_valid_filter_datetime(self): filter = ["a", t_filter_op.FILTER_OP_GT, None] - tbl = Table({ - "a": datetime - }) + tbl = Table({"a": datetime}) assert tbl.is_valid_filter(filter) is False def test_table_is_valid_filter_datetime_str(self): filter = ["a", t_filter_op.FILTER_OP_GT, "7/11/2019 5:30PM"] - tbl = Table({ - "a": datetime - }) + tbl = Table({"a": datetime}) assert tbl.is_valid_filter(filter) is True def test_table_not_is_valid_filter_datetime_str(self): filter = ["a", t_filter_op.FILTER_OP_GT, None] - tbl = Table({ - "a": datetime - }) + tbl = Table({"a": datetime}) assert tbl.is_valid_filter(filter) is False def test_table_is_valid_filter_ignores_not_in_schema(self): @@ -468,94 +303,48 @@ def test_table_index(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 4}] tbl = Table(data, index="a") assert tbl.size() == 1 - assert tbl.view().to_records() == [ - {"a": 1, "b": 4} - ] + assert tbl.view().to_records() == [{"a": 1, "b": 4}] def test_table_index_from_schema(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 4}] - tbl = Table({ - "a": int, - "b": int - }, index="a") + tbl = Table({"a": int, "b": int}, index="a") assert tbl.size() == 0 tbl.update(data) - assert tbl.view().to_records() == [ - {"a": 1, "b": 4} - ] + assert tbl.view().to_records() == [{"a": 1, "b": 4}] # index with None in column def test_table_index_int_with_none(self): - tbl = Table({ - "a": [0, 1, 2, None, None], - "b": [4, 3, 2, 1, 0] - }, index="a") - assert tbl.view().to_dict() == { - "a": [None, 0, 1, 2], # second `None` replaces first - "b": [0, 4, 3, 2] - } + tbl = Table({"a": [0, 1, 2, None, None], "b": [4, 3, 2, 1, 0]}, index="a") + assert tbl.view().to_dict() == {"a": [None, 0, 1, 2], "b": [0, 4, 3, 2]} # second `None` replaces first def test_table_index_float_with_none(self): - tbl = Table({ - "a": [0.0, 1.5, 2.5, None, None], - "b": [4, 3, 2, 1, 0] - }, index="a") - assert tbl.view().to_dict() == { - "a": [None, 0, 1.5, 2.5], # second `None` replaces first - "b": [0, 4, 3, 2] - } + tbl = Table({"a": [0.0, 1.5, 2.5, None, None], "b": [4, 3, 2, 1, 0]}, index="a") + assert tbl.view().to_dict() == {"a": [None, 0, 1.5, 2.5], "b": [0, 4, 3, 2]} # second `None` replaces first def test_table_index_bool_with_none(self): # bools cannot be used as primary key columns with raises(PerspectiveCppError): - Table({ - "a": [True, False, None, True], - "b": [4, 3, 2, 1] - }, index="a") + Table({"a": [True, False, None, True], "b": [4, 3, 2, 1]}, index="a") def test_table_index_date_with_none(self): - tbl = Table({ - "a": [date(2019, 7, 11), None, date(2019, 3, 12), date(2011, 3, 10)], - "b": [4, 3, 2, 1] - }, index="a") - assert tbl.view().to_dict() == { - "a": [None, datetime(2011, 3, 10), datetime(2019, 3, 12), datetime(2019, 7, 11)], - "b": [3, 1, 2, 4] - } + tbl = Table({"a": [date(2019, 7, 11), None, date(2019, 3, 12), date(2011, 3, 10)], "b": [4, 3, 2, 1]}, index="a") + assert tbl.view().to_dict() == {"a": [None, datetime(2011, 3, 10), datetime(2019, 3, 12), datetime(2019, 7, 11)], "b": [3, 1, 2, 4]} def test_table_index_datetime_with_none(self): - tbl = Table({ - "a": [datetime(2019, 7, 11, 15, 30), None, datetime(2019, 7, 11, 12, 10), datetime(2019, 7, 11, 5, 0)], - "b": [4, 3, 2, 1] - }, index="a") - assert tbl.view().to_dict() == { - "a": [None, datetime(2019, 7, 11, 5, 0), datetime(2019, 7, 11, 12, 10), datetime(2019, 7, 11, 15, 30)], - "b": [3, 1, 2, 4] - } + tbl = Table({"a": [datetime(2019, 7, 11, 15, 30), None, datetime(2019, 7, 11, 12, 10), datetime(2019, 7, 11, 5, 0)], "b": [4, 3, 2, 1]}, index="a") + assert tbl.view().to_dict() == {"a": [None, datetime(2019, 7, 11, 5, 0), datetime(2019, 7, 11, 12, 10), datetime(2019, 7, 11, 15, 30)], "b": [3, 1, 2, 4]} def test_table_index_str_with_none(self): - tbl = Table({ - "a": ["", "a", None, "b"], - "b": [4, 3, 2, 1] - }, index="a") - assert tbl.view().to_dict() == { - "a": [None, "", "a", "b"], - "b": [2, 4, 3, 1] - } + tbl = Table({"a": ["", "a", None, "b"], "b": [4, 3, 2, 1]}, index="a") + assert tbl.view().to_dict() == {"a": [None, "", "a", "b"], "b": [2, 4, 3, 1]} def test_table_get_index(self): - tbl = Table({ - "a": ["", "a", None, "b"], - "b": [4, 3, 2, 1] - }, index="a") + tbl = Table({"a": ["", "a", None, "b"], "b": [4, 3, 2, 1]}, index="a") assert tbl.get_index() == "a" def test_table_get_index_none(self): - tbl = Table({ - "a": ["", "a", None, "b"], - "b": [4, 3, 2, 1] - }) + tbl = Table({"a": ["", "a", None, "b"], "b": [4, 3, 2, 1]}) assert tbl.get_index() is None # limit @@ -564,9 +353,7 @@ def test_table_limit(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data, limit=1) assert tbl.size() == 1 - assert tbl.view().to_records() == [ - {"a": 3, "b": 4} - ] + assert tbl.view().to_records() == [{"a": 3, "b": 4}] def test_table_get_limit(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] @@ -602,7 +389,6 @@ def test_table_get_num_views(self): assert tbl.get_num_views() == 0 tbl.delete() - # clear def test_table_clear(self): diff --git a/python/perspective/perspective/tests/table/test_table_arrow.py b/python/perspective/perspective/tests/table/test_table_arrow.py index f5d0445249..f44cd4bdff 100644 --- a/python/perspective/perspective/tests/table/test_table_arrow.py +++ b/python/perspective/perspective/tests/table/test_table_arrow.py @@ -28,53 +28,37 @@ class TestTableArrow(object): # files def test_table_arrow_loads_date32_file(self): - with open(DATE32_ARROW, mode='rb') as file: # b is important -> binary + with open(DATE32_ARROW, mode="rb") as file: # b is important -> binary tbl = Table(file.read()) - assert tbl.schema() == { - "jan-2019": date, - "feb-2020": date, - "mar-2019": date, - "apr-2020": date - } + assert tbl.schema() == {"jan-2019": date, "feb-2020": date, "mar-2019": date, "apr-2020": date} assert tbl.size() == 31 view = tbl.view() assert view.to_columns() == { "jan-2019": [datetime(2019, 1, i) for i in range(1, 32)], "feb-2020": [datetime(2020, 2, i) for i in range(1, 30)] + [None, None], "mar-2019": [datetime(2019, 3, i) for i in range(1, 32)], - "apr-2020": [datetime(2020, 4, i) for i in range(1, 31)] + [None] + "apr-2020": [datetime(2020, 4, i) for i in range(1, 31)] + [None], } def test_table_arrow_loads_date64_file(self): - with open(DATE64_ARROW, mode='rb') as file: # b is important -> binary + with open(DATE64_ARROW, mode="rb") as file: # b is important -> binary tbl = Table(file.read()) - assert tbl.schema() == { - "jan-2019": date, - "feb-2020": date, - "mar-2019": date, - "apr-2020": date - } + assert tbl.schema() == {"jan-2019": date, "feb-2020": date, "mar-2019": date, "apr-2020": date} assert tbl.size() == 31 view = tbl.view() assert view.to_columns() == { "jan-2019": [datetime(2019, 1, i) for i in range(1, 32)], "feb-2020": [datetime(2020, 2, i) for i in range(1, 30)] + [None, None], "mar-2019": [datetime(2019, 3, i) for i in range(1, 32)], - "apr-2020": [datetime(2020, 4, i) for i in range(1, 31)] + [None] + "apr-2020": [datetime(2020, 4, i) for i in range(1, 31)] + [None], } def test_table_arrow_loads_dict_file(self): - with open(DICT_ARROW, mode='rb') as file: # b is important -> binary + with open(DICT_ARROW, mode="rb") as file: # b is important -> binary tbl = Table(file.read()) - assert tbl.schema() == { - "a": str, - "b": str - } + assert tbl.schema() == {"a": str, "b": str} assert tbl.size() == 5 - assert tbl.view().to_dict() == { - "a": ["abc", "def", "def", None, "abc"], - "b": ["klm", "hij", None, "hij", "klm"] - } + assert tbl.view().to_dict() == {"a": ["abc", "def", "def", None, "abc"], "b": ["klm", "hij", None, "hij", "klm"]} # streams @@ -83,24 +67,11 @@ def test_table_arrow_loads_int_stream(self, util): arrow_data = util.make_arrow(names, data) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": int, - "b": int, - "c": int, - "d": int - } - assert tbl.view().to_dict() == { - "a": data[0], - "b": data[1], - "c": data[2], - "d": data[3] - } + assert tbl.schema() == {"a": int, "b": int, "c": int, "d": int} + assert tbl.view().to_dict() == {"a": data[0], "b": data[1], "c": data[2], "d": data[3]} def test_table_arrow_loads_float_stream(self, util): - data = [ - [i for i in range(10)], - [i * 1.5 for i in range(10)] - ] + data = [[i for i in range(10)], [i * 1.5 for i in range(10)]] arrow_data = util.make_arrow(["a", "b"], data) tbl = Table(arrow_data) assert tbl.size() == 10 @@ -108,241 +79,136 @@ def test_table_arrow_loads_float_stream(self, util): "a": int, "b": float, } - assert tbl.view().to_dict() == { - "a": data[0], - "b": data[1] - } + assert tbl.view().to_dict() == {"a": data[0], "b": data[1]} def test_table_arrow_loads_decimal_stream(self, util): - data = [ - [i * 1000 for i in range(10)] - ] + data = [[i * 1000 for i in range(10)]] arrow_data = util.make_arrow(["a"], data, types=[pa.decimal128(4)]) tbl = Table(arrow_data) assert tbl.size() == 10 assert tbl.schema() == { "a": int, } - assert tbl.view().to_dict() == { - "a": data[0] - } + assert tbl.view().to_dict() == {"a": data[0]} def test_table_arrow_loads_bool_stream(self, util): - data = [ - [True if i % 2 == 0 else False for i in range(10)] - ] + data = [[True if i % 2 == 0 else False for i in range(10)]] arrow_data = util.make_arrow(["a"], data) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": bool - } - assert tbl.view().to_dict() == { - "a": data[0] - } + assert tbl.schema() == {"a": bool} + assert tbl.view().to_dict() == {"a": data[0]} def test_table_arrow_loads_date32_stream(self, util): - data = [ - [date(2019, 2, i) for i in range(1, 11)] - ] + data = [[date(2019, 2, i) for i in range(1, 11)]] arrow_data = util.make_arrow(["a"], data, types=[pa.date32()]) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": date - } - assert tbl.view().to_dict() == { - "a": [datetime(2019, 2, i) for i in range(1, 11)] - } + assert tbl.schema() == {"a": date} + assert tbl.view().to_dict() == {"a": [datetime(2019, 2, i) for i in range(1, 11)]} def test_table_arrow_loads_date64_stream(self, util): - data = [ - [date(2019, 2, i) for i in range(1, 11)] - ] + data = [[date(2019, 2, i) for i in range(1, 11)]] arrow_data = util.make_arrow(["a"], data, types=[pa.date64()]) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": date - } - assert tbl.view().to_dict() == { - "a": [datetime(2019, 2, i) for i in range(1, 11)] - } + assert tbl.schema() == {"a": date} + assert tbl.view().to_dict() == {"a": [datetime(2019, 2, i) for i in range(1, 11)]} def test_table_arrow_loads_timestamp_all_formats_stream(self, util): data = [ [datetime(2019, 2, i, 9) for i in range(1, 11)], [datetime(2019, 2, i, 10) for i in range(1, 11)], [datetime(2019, 2, i, 11) for i in range(1, 11)], - [datetime(2019, 2, i, 12) for i in range(1, 11)] + [datetime(2019, 2, i, 12) for i in range(1, 11)], ] arrow_data = util.make_arrow( - names, data, types=[ + names, + data, + types=[ pa.timestamp("s"), pa.timestamp("ms"), pa.timestamp("us"), pa.timestamp("ns"), - ] + ], ) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": datetime, - "b": datetime, - "c": datetime, - "d": datetime - } - assert tbl.view().to_dict() == { - "a": data[0], - "b": data[1], - "c": data[2], - "d": data[3] - } + assert tbl.schema() == {"a": datetime, "b": datetime, "c": datetime, "d": datetime} + assert tbl.view().to_dict() == {"a": data[0], "b": data[1], "c": data[2], "d": data[3]} def test_table_arrow_loads_string_stream(self, util): - data = [ - [str(i) for i in range(10)] - ] + data = [[str(i) for i in range(10)]] arrow_data = util.make_arrow(["a"], data, types=[pa.string()]) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": str - } - assert tbl.view().to_dict() == { - "a": data[0] - } + assert tbl.schema() == {"a": str} + assert tbl.view().to_dict() == {"a": data[0]} def test_table_arrow_loads_dictionary_stream_int8(self, util): - data = [ - ([0, 1, 1, None], ["abc", "def"]), - ([0, 1, None, 2], ["xx", "yy", "zz"]) - ] + data = [([0, 1, 1, None], ["abc", "def"]), ([0, 1, None, 2], ["xx", "yy", "zz"])] types = [[pa.int8(), pa.string()]] * 2 - arrow_data = util.make_dictionary_arrow(["a", "b"], - data, - types=types) + arrow_data = util.make_dictionary_arrow(["a", "b"], data, types=types) tbl = Table(arrow_data) assert tbl.size() == 4 - assert tbl.schema() == { - "a": str, - "b": str - } - assert tbl.view().to_dict() == { - "a": ["abc", "def", "def", None], - "b": ["xx", "yy", None, "zz"] - } + assert tbl.schema() == {"a": str, "b": str} + assert tbl.view().to_dict() == {"a": ["abc", "def", "def", None], "b": ["xx", "yy", None, "zz"]} def test_table_arrow_loads_dictionary_stream_int16(self, util): - data = [ - ([0, 1, 1, None], ["abc", "def"]), - ([0, 1, None, 2], ["xx", "yy", "zz"]) - ] + data = [([0, 1, 1, None], ["abc", "def"]), ([0, 1, None, 2], ["xx", "yy", "zz"])] types = [[pa.int16(), pa.string()]] * 2 - arrow_data = util.make_dictionary_arrow(["a", "b"], - data, - types=types) + arrow_data = util.make_dictionary_arrow(["a", "b"], data, types=types) tbl = Table(arrow_data) assert tbl.size() == 4 - assert tbl.schema() == { - "a": str, - "b": str - } - assert tbl.view().to_dict() == { - "a": ["abc", "def", "def", None], - "b": ["xx", "yy", None, "zz"] - } + assert tbl.schema() == {"a": str, "b": str} + assert tbl.view().to_dict() == {"a": ["abc", "def", "def", None], "b": ["xx", "yy", None, "zz"]} def test_table_arrow_loads_dictionary_stream_int32(self, util): - data = [ - ([0, 1, 1, None], ["abc", "def"]), - ([0, 1, None, 2], ["xx", "yy", "zz"]) - ] + data = [([0, 1, 1, None], ["abc", "def"]), ([0, 1, None, 2], ["xx", "yy", "zz"])] types = [[pa.int32(), pa.string()]] * 2 - arrow_data = util.make_dictionary_arrow(["a", "b"], - data, - types=types) + arrow_data = util.make_dictionary_arrow(["a", "b"], data, types=types) tbl = Table(arrow_data) assert tbl.size() == 4 - assert tbl.schema() == { - "a": str, - "b": str - } - assert tbl.view().to_dict() == { - "a": ["abc", "def", "def", None], - "b": ["xx", "yy", None, "zz"] - } + assert tbl.schema() == {"a": str, "b": str} + assert tbl.view().to_dict() == {"a": ["abc", "def", "def", None], "b": ["xx", "yy", None, "zz"]} def test_table_arrow_loads_dictionary_stream_int64(self, util): - data = [ - ([0, 1, 1, None], ["abc", "def"]), - ([0, 1, None, 2], ["xx", "yy", "zz"]) - ] + data = [([0, 1, 1, None], ["abc", "def"]), ([0, 1, None, 2], ["xx", "yy", "zz"])] arrow_data = util.make_dictionary_arrow(["a", "b"], data) tbl = Table(arrow_data) assert tbl.size() == 4 - assert tbl.schema() == { - "a": str, - "b": str - } - assert tbl.view().to_dict() == { - "a": ["abc", "def", "def", None], - "b": ["xx", "yy", None, "zz"] - } + assert tbl.schema() == {"a": str, "b": str} + assert tbl.view().to_dict() == {"a": ["abc", "def", "def", None], "b": ["xx", "yy", None, "zz"]} def test_table_arrow_loads_dictionary_stream_nones(self, util): - data = [ - ([None, 0, 1, 2], ["", "abc", "def"]) - ] + data = [([None, 0, 1, 2], ["", "abc", "def"])] arrow_data = util.make_dictionary_arrow(["a"], data) tbl = Table(arrow_data) assert tbl.size() == 4 - assert tbl.schema() == { - "a": str - } - assert tbl.view().to_dict() == { - "a": [None, "", "abc", "def"] - } + assert tbl.schema() == {"a": str} + assert tbl.view().to_dict() == {"a": [None, "", "abc", "def"]} def test_table_arrow_loads_dictionary_stream_nones_indexed(self, util): - data = [ - ([1, None, 0, 2], ["", "abc", "def"]), # ["abc", None, "", "def"] - ([2, 1, 0, None], ["", "hij", "klm"]) # ["klm", "hij", "", None] - ] + data = [([1, None, 0, 2], ["", "abc", "def"]), ([2, 1, 0, None], ["", "hij", "klm"])] # ["abc", None, "", "def"] # ["klm", "hij", "", None] arrow_data = util.make_dictionary_arrow(["a", "b"], data) tbl = Table(arrow_data, index="a") # column "a" is sorted - assert tbl.schema() == { - "a": str, - "b": str - } - assert tbl.view().to_dict() == { - "a": [None, "", "abc", "def"], - "b": ["hij", "", "klm", None] - } + assert tbl.schema() == {"a": str, "b": str} + assert tbl.view().to_dict() == {"a": [None, "", "abc", "def"], "b": ["hij", "", "klm", None]} def test_table_arrow_loads_dictionary_stream_nones_indexed_2(self, util): """Test the other column, just in case.""" - data = [ - ([1, None, 0, 2], ["", "abc", "def"]), # ["abc", None, "", "def"] - ([2, 1, 0, None], ["", "hij", "klm"]) # ["klm", "hij", "", None] - ] + data = [([1, None, 0, 2], ["", "abc", "def"]), ([2, 1, 0, None], ["", "hij", "klm"])] # ["abc", None, "", "def"] # ["klm", "hij", "", None] arrow_data = util.make_dictionary_arrow(["a", "b"], data) tbl = Table(arrow_data, index="b") # column "b" is sorted - assert tbl.schema() == { - "a": str, - "b": str - } - assert tbl.view().to_dict() == { - "a": ["def", "", None, "abc"], - "b": [None, "", "hij", "klm"] - } + assert tbl.schema() == {"a": str, "b": str} + assert tbl.view().to_dict() == {"a": ["def", "", None, "abc"], "b": [None, "", "hij", "klm"]} # legacy @@ -351,18 +217,10 @@ def test_table_arrow_loads_int_legacy(self, util): arrow_data = util.make_arrow(names, data, legacy=True) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": int, - "b": int, - "c": int, - "d": int - } + assert tbl.schema() == {"a": int, "b": int, "c": int, "d": int} def test_table_arrow_loads_float_legacy(self, util): - data = [ - [i for i in range(10)], - [i * 1.5 for i in range(10)] - ] + data = [[i for i in range(10)], [i * 1.5 for i in range(10)]] arrow_data = util.make_arrow(["a", "b"], data, legacy=True) tbl = Table(arrow_data) assert tbl.size() == 10 @@ -370,138 +228,84 @@ def test_table_arrow_loads_float_legacy(self, util): "a": int, "b": float, } - assert tbl.view().to_dict() == { - "a": data[0], - "b": data[1] - } + assert tbl.view().to_dict() == {"a": data[0], "b": data[1]} def test_table_arrow_loads_decimal128_legacy(self, util): - data = [ - [i * 1000 for i in range(10)] - ] - arrow_data = util.make_arrow( - ["a"], data, types=[pa.decimal128(4)], legacy=True) + data = [[i * 1000 for i in range(10)]] + arrow_data = util.make_arrow(["a"], data, types=[pa.decimal128(4)], legacy=True) tbl = Table(arrow_data) assert tbl.size() == 10 assert tbl.schema() == { "a": int, } - assert tbl.view().to_dict() == { - "a": data[0] - } + assert tbl.view().to_dict() == {"a": data[0]} def test_table_arrow_loads_bool_legacy(self, util): - data = [ - [True if i % 2 == 0 else False for i in range(10)] - ] + data = [[True if i % 2 == 0 else False for i in range(10)]] arrow_data = util.make_arrow(["a"], data, legacy=True) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": bool - } - assert tbl.view().to_dict() == { - "a": data[0] - } + assert tbl.schema() == {"a": bool} + assert tbl.view().to_dict() == {"a": data[0]} def test_table_arrow_loads_date32_legacy(self, util): - data = [ - [date(2019, 2, i) for i in range(1, 11)] - ] - arrow_data = util.make_arrow( - ["a"], data, types=[pa.date32()], legacy=True) + data = [[date(2019, 2, i) for i in range(1, 11)]] + arrow_data = util.make_arrow(["a"], data, types=[pa.date32()], legacy=True) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": date - } - assert tbl.view().to_dict() == { - "a": [datetime(2019, 2, i) for i in range(1, 11)] - } + assert tbl.schema() == {"a": date} + assert tbl.view().to_dict() == {"a": [datetime(2019, 2, i) for i in range(1, 11)]} def test_table_arrow_loads_date64_legacy(self, util): - data = [ - [date(2019, 2, i) for i in range(1, 11)] - ] - arrow_data = util.make_arrow( - ["a"], data, types=[pa.date64()], legacy=True) + data = [[date(2019, 2, i) for i in range(1, 11)]] + arrow_data = util.make_arrow(["a"], data, types=[pa.date64()], legacy=True) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": date - } - assert tbl.view().to_dict() == { - "a": [datetime(2019, 2, i) for i in range(1, 11)] - } + assert tbl.schema() == {"a": date} + assert tbl.view().to_dict() == {"a": [datetime(2019, 2, i) for i in range(1, 11)]} def test_table_arrow_loads_timestamp_all_formats_legacy(self, util): data = [ [datetime(2019, 2, i, 9) for i in range(1, 11)], [datetime(2019, 2, i, 10) for i in range(1, 11)], [datetime(2019, 2, i, 11) for i in range(1, 11)], - [datetime(2019, 2, i, 12) for i in range(1, 11)] + [datetime(2019, 2, i, 12) for i in range(1, 11)], ] arrow_data = util.make_arrow( - names, data, types=[ + names, + data, + types=[ pa.timestamp("s"), pa.timestamp("ms"), pa.timestamp("us"), pa.timestamp("ns"), - ], legacy=True + ], + legacy=True, ) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": datetime, - "b": datetime, - "c": datetime, - "d": datetime - } - assert tbl.view().to_dict() == { - "a": data[0], - "b": data[1], - "c": data[2], - "d": data[3] - } + assert tbl.schema() == {"a": datetime, "b": datetime, "c": datetime, "d": datetime} + assert tbl.view().to_dict() == {"a": data[0], "b": data[1], "c": data[2], "d": data[3]} def test_table_arrow_loads_string_legacy(self, util): - data = [ - [str(i) for i in range(10)] - ] - arrow_data = util.make_arrow( - ["a"], data, types=[pa.string()], legacy=True) + data = [[str(i) for i in range(10)]] + arrow_data = util.make_arrow(["a"], data, types=[pa.string()], legacy=True) tbl = Table(arrow_data) assert tbl.size() == 10 - assert tbl.schema() == { - "a": str - } - assert tbl.view().to_dict() == { - "a": data[0] - } + assert tbl.schema() == {"a": str} + assert tbl.view().to_dict() == {"a": data[0]} def test_table_arrow_loads_dictionary_legacy(self, util): - data = [ - ([0, 1, 1, None], ["a", "b"]), - ([0, 1, None, 2], ["x", "y", "z"]) - ] - arrow_data = util.make_dictionary_arrow( - ["a", "b"], data, legacy=True) + data = [([0, 1, 1, None], ["a", "b"]), ([0, 1, None, 2], ["x", "y", "z"])] + arrow_data = util.make_dictionary_arrow(["a", "b"], data, legacy=True) tbl = Table(arrow_data) assert tbl.size() == 4 - assert tbl.schema() == { - "a": str, - "b": str - } - assert tbl.view().to_dict() == { - "a": ["a", "b", "b", None], - "b": ["x", "y", None, "z"] - } + assert tbl.schema() == {"a": str, "b": str} + assert tbl.view().to_dict() == {"a": ["a", "b", "b", None], "b": ["x", "y", None, "z"]} def test_table_arrow_loads_arrow_from_df_with_nan(self): - data = pd.DataFrame({ - "a": [1.5, 2.5, np.nan, 3.5, 4.5, np.nan, np.nan, np.nan] - }) + data = pd.DataFrame({"a": [1.5, 2.5, np.nan, 3.5, 4.5, np.nan, np.nan, np.nan]}) arrow_table = pa.Table.from_pandas(data, preserve_index=False) @@ -509,8 +313,7 @@ def test_table_arrow_loads_arrow_from_df_with_nan(self): # write arrow to stream stream = pa.BufferOutputStream() - writer = pa.RecordBatchStreamWriter( - stream, arrow_table.schema, use_legacy_format=False) + writer = pa.RecordBatchStreamWriter(stream, arrow_table.schema, use_legacy_format=False) writer.write_table(arrow_table) writer.close() arrow = stream.getvalue().to_pybytes() @@ -520,9 +323,7 @@ def test_table_arrow_loads_arrow_from_df_with_nan(self): assert tbl.size() == 8 # check types - assert tbl.schema() == { - "a": float - } + assert tbl.schema() == {"a": float} # check nans json = tbl.view().to_columns() diff --git a/python/perspective/perspective/tests/table/test_table_datetime.py b/python/perspective/perspective/tests/table/test_table_datetime.py index c33ccb6a52..1d201833c3 100644 --- a/python/perspective/perspective/tests/table/test_table_datetime.py +++ b/python/perspective/perspective/tests/table/test_table_datetime.py @@ -20,19 +20,10 @@ from pytest import mark from perspective.table import Table -LOCAL_DATETIMES = [ - datetime(2019, 1, 11, 0, 10, 20), - datetime(2019, 1, 11, 11, 10, 20), - datetime(2019, 1, 11, 19, 10, 20) -] +LOCAL_DATETIMES = [datetime(2019, 1, 11, 0, 10, 20), datetime(2019, 1, 11, 11, 10, 20), datetime(2019, 1, 11, 19, 10, 20)] # Test the DST transition for Continental US -LOCAL_DATETIMES_DST = [ - datetime(2019, 3, 9, 12, 10, 20), - datetime(2019, 3, 19, 12, 10, 20), - datetime(2019, 11, 2, 12, 10, 20), - datetime(2019, 11, 3, 12, 10, 20) -] +LOCAL_DATETIMES_DST = [datetime(2019, 3, 9, 12, 10, 20), datetime(2019, 3, 19, 12, 10, 20), datetime(2019, 11, 2, 12, 10, 20), datetime(2019, 11, 3, 12, 10, 20)] LOCAL_TIMESTAMPS = [pd.Timestamp(d) for d in LOCAL_DATETIMES] LOCAL_TIMESTAMPS_DST = [pd.Timestamp(d) for d in LOCAL_DATETIMES_DST] @@ -68,13 +59,14 @@ TZ_DATETIMES_DST[TZ.zone] = [d.astimezone(TZ) for d in UTC_DATETIMES_DST] TZ_TIMESTAMPS_DST[TZ.zone] = [d.tz_convert(TZ) for d in UTC_TIMESTAMPS_DST] -if os.name != 'nt': +if os.name != "nt": # no tzset on windows, run these tests on linux/mac only class TestTableLocalDateTime(object): """Test datetimes across configurations such as local time, timezone-aware, timezone-naive, and UTC implementations. """ + def setup_method(self): # To make sure that local times are not changed, set timezone to EST os.environ["TZ"] = "US/Eastern" @@ -89,23 +81,17 @@ def test_table_should_assume_local_time(self): """If a datetime object has no `tzinfo`, it should be assumed to be in local time and not be converted at all. """ - data = { - "a": LOCAL_DATETIMES - } + data = {"a": LOCAL_DATETIMES} table = Table(data) assert table.view().to_dict()["a"] == LOCAL_DATETIMES def test_table_should_assume_local_time_numpy_datetime64(self): - data = { - "a": [np.datetime64(d) for d in LOCAL_DATETIMES] - } + data = {"a": [np.datetime64(d) for d in LOCAL_DATETIMES]} table = Table(data) assert table.view().to_dict()["a"] == LOCAL_DATETIMES def test_table_should_assume_local_time_pandas_timestamp(self): - data = { - "a": LOCAL_TIMESTAMPS - } + data = {"a": LOCAL_TIMESTAMPS} # Timestamps are assumed to be in UTC by pandas table = Table(data) @@ -114,158 +100,94 @@ def test_table_should_assume_local_time_pandas_timestamp(self): assert table.view().to_dict()["a"] == LOCAL_DATETIMES def test_table_should_assume_local_time_pandas_timestamp_df(self): - data = pd.DataFrame({ - "a": LOCAL_TIMESTAMPS - }) + data = pd.DataFrame({"a": LOCAL_TIMESTAMPS}) # Timestamps are assumed to be in UTC by pandas table = Table(data) # Timestamps are read out in local time - assert table.view().to_dict()["a"] == [ - datetime(2019, 1, 10, 19, 10, 20), - datetime(2019, 1, 11, 6, 10, 20), - datetime(2019, 1, 11, 14, 10, 20) - ] + assert table.view().to_dict()["a"] == [datetime(2019, 1, 10, 19, 10, 20), datetime(2019, 1, 11, 6, 10, 20), datetime(2019, 1, 11, 14, 10, 20)] def test_table_should_assume_local_time_dst(self): """If a datetime object has no `tzinfo`, it should be assumed to be in local time and not be converted at all. """ - data = { - "a": LOCAL_DATETIMES_DST - } + data = {"a": LOCAL_DATETIMES_DST} table = Table(data) assert table.view().to_dict()["a"] == LOCAL_DATETIMES_DST def test_table_should_assume_local_time_numpy_datetime64_dst(self): - data = { - "a": [np.datetime64(d) for d in LOCAL_DATETIMES_DST] - } + data = {"a": [np.datetime64(d) for d in LOCAL_DATETIMES_DST]} table = Table(data) assert table.view().to_dict()["a"] == LOCAL_DATETIMES_DST def test_table_should_assume_local_time_pandas_timestamp_dst(self): - data = { - "a": LOCAL_TIMESTAMPS_DST - } + data = {"a": LOCAL_TIMESTAMPS_DST} table = Table(data) assert table.view().to_dict()["a"] == LOCAL_DATETIMES_DST def test_table_should_assume_local_time_pandas_timestamp_dst_df(self): - data = pd.DataFrame({ - "a": LOCAL_TIMESTAMPS_DST - }) + data = pd.DataFrame({"a": LOCAL_TIMESTAMPS_DST}) table = Table(data) - assert table.view().to_dict()["a"] == [ - datetime(2019, 3, 9, 7, 10, 20), - datetime(2019, 3, 19, 8, 10, 20), - datetime(2019, 11, 2, 8, 10, 20), - datetime(2019, 11, 3, 7, 10, 20) - ] + assert table.view().to_dict()["a"] == [datetime(2019, 3, 9, 7, 10, 20), datetime(2019, 3, 19, 8, 10, 20), datetime(2019, 11, 2, 8, 10, 20), datetime(2019, 11, 3, 7, 10, 20)] def test_table_datetime_min(self): - data = { - "a": [datetime.min] - } + data = {"a": [datetime.min]} table = Table(data) - assert table.view().to_dict()["a"] == [ - datetime(1969, 12, 31, 19, 0) - ] + assert table.view().to_dict()["a"] == [datetime(1969, 12, 31, 19, 0)] def test_table_datetime_min_df(self): - data = pd.DataFrame({ - "a": [datetime.min] - }) + data = pd.DataFrame({"a": [datetime.min]}) table = Table(data) - assert table.view().to_dict()["a"] == [ - datetime(1969, 12, 31, 19, 0) - ] + assert table.view().to_dict()["a"] == [datetime(1969, 12, 31, 19, 0)] def test_table_datetime_1900(self): - data = { - "a": [datetime(1900, 1, 1)] - } + data = {"a": [datetime(1900, 1, 1)]} table = Table(data) - assert table.view().to_dict()["a"] == [ - datetime(1900, 1, 1) - ] + assert table.view().to_dict()["a"] == [datetime(1900, 1, 1)] def test_table_datetime_1900_df(self): - data = pd.DataFrame({ - "a": [datetime(1900, 1, 1)] - }) + data = pd.DataFrame({"a": [datetime(1900, 1, 1)]}) table = Table(data) - assert table.view().to_dict()["a"] == [ - datetime(1899, 12, 31, 19) - ] + assert table.view().to_dict()["a"] == [datetime(1899, 12, 31, 19)] def test_table_datetime_1899(self): - data = { - "a": [datetime(1899, 1, 1)] - } + data = {"a": [datetime(1899, 1, 1)]} table = Table(data) - assert table.view().to_dict()["a"] == [ - datetime(1898, 12, 31, 19) - ] + assert table.view().to_dict()["a"] == [datetime(1898, 12, 31, 19)] def test_table_datetime_1899_df(self): - data = pd.DataFrame({ - "a": [datetime(1899, 1, 1)] - }) + data = pd.DataFrame({"a": [datetime(1899, 1, 1)]}) table = Table(data) - assert table.view().to_dict()["a"] == [ - datetime(1898, 12, 31, 19) - ] + assert table.view().to_dict()["a"] == [datetime(1898, 12, 31, 19)] def test_table_datetime_min_epoch(self): - data = { - "a": [0] - } - table = Table({ - "a": datetime - }) + data = {"a": [0]} + table = Table({"a": datetime}) table.update(data) - assert table.view().to_dict()["a"] == [ - datetime(1969, 12, 31, 19, 0) - ] + assert table.view().to_dict()["a"] == [datetime(1969, 12, 31, 19, 0)] def test_table_datetime_min_epoch_df(self): - data = pd.DataFrame({ - "a": [0] - }) - table = Table({ - "a": datetime - }) + data = pd.DataFrame({"a": [0]}) + table = Table({"a": datetime}) table.update(data) - assert table.view().to_dict()["a"] == [ - datetime(1969, 12, 31, 19, 0) - ] + assert table.view().to_dict()["a"] == [datetime(1969, 12, 31, 19, 0)] @mark.skip def test_table_datetime_max(self): - data = { - "a": [datetime.max] - } + data = {"a": [datetime.max]} table = Table(data) # lol - result is converted from UTC to EST (local time) - assert table.view().to_dict()["a"] == [ - datetime(9999, 12, 31, 18, 59, 59) - ] + assert table.view().to_dict()["a"] == [datetime(9999, 12, 31, 18, 59, 59)] @mark.skip def test_table_datetime_max_df(self): - data = pd.DataFrame({ - "a": [datetime.max] - }) + data = pd.DataFrame({"a": [datetime.max]}) table = Table(data) - assert table.view().to_dict()["a"] == [ - datetime(9999, 12, 31, 18, 59, 59) - ] + assert table.view().to_dict()["a"] == [datetime(9999, 12, 31, 18, 59, 59)] class TestTableDateTimeUTCToLocal(object): - def teardown_method(self): # Set timezone to UTC, always os.environ["TZ"] = "UTC" @@ -276,216 +198,154 @@ def test_table_should_convert_UTC_to_local_time_pytz_pacific(self): UTC. Make sure this works with both `pytz` and `dateutil` for `datetime` and `pandas.Timestamp`. """ - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "US/Pacific" time.tzset() # Should be in PST now - assert table.view().to_dict() == { - "a": [d.astimezone(PST).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(PST).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_pytz_central(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "US/Central" time.tzset() # Should be in CST now - assert table.view().to_dict() == { - "a": [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_pytz_eastern(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "US/Eastern" time.tzset() # Should be in EST now - assert table.view().to_dict() == { - "a": [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_pytz_GMT(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "GMT" time.tzset() # Should be in GMT now - assert table.view().to_dict() == { - "a": [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_pytz_HKT(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "Asia/Hong_Kong" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_pytz_JPT(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "Asia/Tokyo" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_pytz_ACT(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "Australia/Sydney" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_dateutil_pacific(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "US/Pacific" time.tzset() # Should be in PST now - assert table.view().to_dict() == { - "a": [d.astimezone(PST).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(PST).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_dateutil_central(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "US/Central" time.tzset() # Should be in CST now - assert table.view().to_dict() == { - "a": [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_dateutil_eastern(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "US/Eastern" time.tzset() # Should be in EST now - assert table.view().to_dict() == { - "a": [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_dateutil_GMT(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "GMT" time.tzset() # Should be in GMT now - assert table.view().to_dict() == { - "a": [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_dateutil_pacific_DST(self): - data = { - "a": UTC_DATETIMES_DST - } + data = {"a": UTC_DATETIMES_DST} table = Table(data) os.environ["TZ"] = "US/Pacific" time.tzset() # Should be in PST now - assert table.view().to_dict() == { - "a": [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["US/Pacific"]] - } + assert table.view().to_dict() == {"a": [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["US/Pacific"]]} def test_table_should_convert_UTC_to_local_time_dateutil_central_DST(self): - data = { - "a": UTC_DATETIMES_DST - } + data = {"a": UTC_DATETIMES_DST} table = Table(data) os.environ["TZ"] = "US/Central" time.tzset() # Should be in CST now - assert table.view().to_dict() == { - "a": [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["US/Central"]] - } + assert table.view().to_dict() == {"a": [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["US/Central"]]} def test_table_should_convert_UTC_to_local_time_dateutil_eastern_DST(self): - data = { - "a": UTC_DATETIMES_DST - } + data = {"a": UTC_DATETIMES_DST} table = Table(data) os.environ["TZ"] = "US/Eastern" time.tzset() # Should be in EST now - assert table.view().to_dict() == { - "a": [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["US/Eastern"]] - } + assert table.view().to_dict() == {"a": [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["US/Eastern"]]} def test_table_should_convert_UTC_to_local_time_dateutil_GMT_DST(self): - data = { - "a": UTC_DATETIMES_DST - } + data = {"a": UTC_DATETIMES_DST} table = Table(data) os.environ["TZ"] = "GMT" time.tzset() # Should be in GMT now - assert table.view().to_dict() == { - "a": [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["GMT"]] - } + assert table.view().to_dict() == {"a": [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["GMT"]]} def test_table_should_convert_UTC_to_local_time_dateutil_pacific_DST_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS_DST - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS_DST}) table = Table(data) os.environ["TZ"] = "US/Pacific" @@ -495,9 +355,7 @@ def test_table_should_convert_UTC_to_local_time_dateutil_pacific_DST_timestamp(s assert table.view().to_dict()["a"] == [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["US/Pacific"]] def test_table_should_convert_UTC_to_local_time_dateutil_central_DST_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS_DST - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS_DST}) table = Table(data) os.environ["TZ"] = "US/Central" @@ -507,9 +365,7 @@ def test_table_should_convert_UTC_to_local_time_dateutil_central_DST_timestamp(s assert table.view().to_dict()["a"] == [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["US/Central"]] def test_table_should_convert_UTC_to_local_time_dateutil_eastern_DST_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS_DST - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS_DST}) table = Table(data) os.environ["TZ"] = "US/Eastern" @@ -519,9 +375,7 @@ def test_table_should_convert_UTC_to_local_time_dateutil_eastern_DST_timestamp(s assert table.view().to_dict()["a"] == [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["US/Eastern"]] def test_table_should_convert_UTC_to_local_time_dateutil_GMT_DST_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS_DST - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS_DST}) table = Table(data) os.environ["TZ"] = "GMT" @@ -531,35 +385,25 @@ def test_table_should_convert_UTC_to_local_time_dateutil_GMT_DST_timestamp(self) assert table.view().to_dict()["a"] == [d.replace(tzinfo=None) for d in TZ_DATETIMES_DST["GMT"]] def test_table_should_convert_UTC_to_local_time_dateutil_HKT(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "Asia/Hong_Kong" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_dateutil_JPT(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "Asia/Tokyo" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_dateutil_ACT(self): - data = { - "a": UTC_DATETIMES - } + data = {"a": UTC_DATETIMES} table = Table(data) os.environ["TZ"] = "Australia/Sydney" @@ -567,14 +411,10 @@ def test_table_should_convert_UTC_to_local_time_dateutil_ACT(self): ACT = tz.gettz("Australia/Sydney") - assert table.view().to_dict() == { - "a": [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_UTC_to_local_time_pytz_pacific_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "US/Pacific" @@ -584,9 +424,7 @@ def test_table_should_convert_UTC_to_local_time_pytz_pacific_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(PST).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_pytz_central_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "US/Central" @@ -596,9 +434,7 @@ def test_table_should_convert_UTC_to_local_time_pytz_central_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_pytz_eastern_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "US/Eastern" @@ -608,9 +444,7 @@ def test_table_should_convert_UTC_to_local_time_pytz_eastern_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_pytz_GMT_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "GMT" @@ -620,9 +454,7 @@ def test_table_should_convert_UTC_to_local_time_pytz_GMT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_pytz_HKT_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "Asia/Hong_Kong" @@ -631,9 +463,7 @@ def test_table_should_convert_UTC_to_local_time_pytz_HKT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_pytz_JPT_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "Asia/Tokyo" @@ -642,9 +472,7 @@ def test_table_should_convert_UTC_to_local_time_pytz_JPT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_pytz_ACT_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "Australia/Sydney" @@ -653,9 +481,7 @@ def test_table_should_convert_UTC_to_local_time_pytz_ACT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_dateutil_pacific_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "US/Pacific" @@ -665,9 +491,7 @@ def test_table_should_convert_UTC_to_local_time_dateutil_pacific_timestamp(self) assert table.view().to_dict()["a"] == [d.astimezone(PST).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_dateutil_central_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "US/Central" @@ -679,9 +503,7 @@ def test_table_should_convert_UTC_to_local_time_dateutil_central_timestamp(self) assert table.view().to_dict()["a"] == [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_dateutil_eastern_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "US/Eastern" @@ -691,9 +513,7 @@ def test_table_should_convert_UTC_to_local_time_dateutil_eastern_timestamp(self) assert table.view().to_dict()["a"] == [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_dateutil_GMT_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "GMT" @@ -705,9 +525,7 @@ def test_table_should_convert_UTC_to_local_time_dateutil_GMT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_dateutil_HKT_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "Asia/Hong_Kong" @@ -716,9 +534,7 @@ def test_table_should_convert_UTC_to_local_time_dateutil_HKT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_dateutil_JPT_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "Asia/Tokyo" @@ -727,9 +543,7 @@ def test_table_should_convert_UTC_to_local_time_dateutil_JPT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_UTC_to_local_time_dateutil_ACT_timestamp(self): - data = pd.DataFrame({ - "a": UTC_TIMESTAMPS - }) + data = pd.DataFrame({"a": UTC_TIMESTAMPS}) table = Table(data) os.environ["TZ"] = "Australia/Sydney" @@ -738,178 +552,127 @@ def test_table_should_convert_UTC_to_local_time_dateutil_ACT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]] class TestTableDateTimeArbitaryToLocal(object): - def teardown_method(self): # Set timezone to UTC, always os.environ["TZ"] = "UTC" time.tzset() def test_table_should_convert_PST_to_local_time_pytz_central(self): - data = { - "a": TZ_DATETIMES["US/Pacific"] - } + data = {"a": TZ_DATETIMES["US/Pacific"]} table = Table(data) os.environ["TZ"] = "US/Central" time.tzset() # Should be in CST now - assert table.view().to_dict() == { - "a": [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_CST_to_local_time_pytz_eastern(self): - data = { - "a": TZ_DATETIMES["US/Central"] - } + data = {"a": TZ_DATETIMES["US/Central"]} table = Table(data) os.environ["TZ"] = "US/Eastern" time.tzset() # Should be in EST now - assert table.view().to_dict() == { - "a": [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_EST_to_local_time_pytz_GMT(self): - data = { - "a": TZ_DATETIMES["US/Eastern"] - } + data = {"a": TZ_DATETIMES["US/Eastern"]} table = Table(data) os.environ["TZ"] = "GMT" time.tzset() # Should be in GMT now - assert table.view().to_dict() == { - "a": [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_GMT_to_local_time_pytz_HKT(self): - data = { - "a": TZ_DATETIMES["GMT"] - } + data = {"a": TZ_DATETIMES["GMT"]} table = Table(data) os.environ["TZ"] = "Asia/Hong_Kong" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_HKT_to_local_time_pytz_JPT(self): - data = { - "a": TZ_DATETIMES["Asia/Hong_Kong"] - } + data = {"a": TZ_DATETIMES["Asia/Hong_Kong"]} table = Table(data) os.environ["TZ"] = "Asia/Tokyo" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_JPT_to_local_time_pytz_ACT(self): - data = { - "a": TZ_DATETIMES["Asia/Tokyo"] - } + data = {"a": TZ_DATETIMES["Asia/Tokyo"]} table = Table(data) os.environ["TZ"] = "Australia/Sydney" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_PST_to_local_time_dateutil_central(self): - data = { - "a": TZ_DATETIMES["US/Pacific"] - } + data = {"a": TZ_DATETIMES["US/Pacific"]} table = Table(data) os.environ["TZ"] = "US/Central" time.tzset() # Should be in CST now - assert table.view().to_dict() == { - "a": [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_CST_to_local_time_dateutil_eastern(self): - data = { - "a": TZ_DATETIMES["US/Central"] - } + data = {"a": TZ_DATETIMES["US/Central"]} table = Table(data) os.environ["TZ"] = "US/Eastern" time.tzset() # Should be in EST now - assert table.view().to_dict() == { - "a": [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_EST_to_local_time_dateutil_GMT(self): - data = { - "a": TZ_DATETIMES["US/Eastern"] - } + data = {"a": TZ_DATETIMES["US/Eastern"]} table = Table(data) os.environ["TZ"] = "GMT" time.tzset() # Should be in GMT now - assert table.view().to_dict() == { - "a": [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_GMT_to_local_time_dateutil_HKT(self): - data = { - "a": TZ_DATETIMES["GMT"] - } + data = {"a": TZ_DATETIMES["GMT"]} table = Table(data) os.environ["TZ"] = "Asia/Hong_Kong" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_HKT_to_local_time_dateutil_JPT(self): - data = { - "a": TZ_DATETIMES["Asia/Hong_Kong"] - } + data = {"a": TZ_DATETIMES["Asia/Hong_Kong"]} table = Table(data) os.environ["TZ"] = "Asia/Tokyo" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_JPT_to_local_time_dateutil_ACT(self): - data = { - "a": TZ_DATETIMES["Asia/Tokyo"] - } + data = {"a": TZ_DATETIMES["Asia/Tokyo"]} table = Table(data) os.environ["TZ"] = "Australia/Sydney" time.tzset() - assert table.view().to_dict() == { - "a": [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]] - } + assert table.view().to_dict() == {"a": [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]]} def test_table_should_convert_PST_to_local_time_pytz_central_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["US/Pacific"] - } + data = {"a": TZ_TIMESTAMPS["US/Pacific"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "US/Central" @@ -919,9 +682,7 @@ def test_table_should_convert_PST_to_local_time_pytz_central_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_CST_to_local_time_pytz_eastern_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["US/Central"] - } + data = {"a": TZ_TIMESTAMPS["US/Central"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "US/Eastern" @@ -931,9 +692,7 @@ def test_table_should_convert_CST_to_local_time_pytz_eastern_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_EST_to_local_time_pytz_GMT_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["US/Eastern"] - } + data = {"a": TZ_TIMESTAMPS["US/Eastern"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "GMT" @@ -943,9 +702,7 @@ def test_table_should_convert_EST_to_local_time_pytz_GMT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_GMT_to_local_time_pytz_HKT_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["GMT"] - } + data = {"a": TZ_TIMESTAMPS["GMT"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "Asia/Hong_Kong" @@ -954,9 +711,7 @@ def test_table_should_convert_GMT_to_local_time_pytz_HKT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_HKT_to_local_time_pytz_JPT_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["Asia/Hong_Kong"] - } + data = {"a": TZ_TIMESTAMPS["Asia/Hong_Kong"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "Asia/Tokyo" @@ -965,9 +720,7 @@ def test_table_should_convert_HKT_to_local_time_pytz_JPT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_JPT_to_local_time_pytz_ACT_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["Asia/Tokyo"] - } + data = {"a": TZ_TIMESTAMPS["Asia/Tokyo"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "Australia/Sydney" @@ -976,9 +729,7 @@ def test_table_should_convert_JPT_to_local_time_pytz_ACT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(ACT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_PST_to_local_time_dateutil_central_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["US/Pacific"] - } + data = {"a": TZ_TIMESTAMPS["US/Pacific"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "US/Central" @@ -988,9 +739,7 @@ def test_table_should_convert_PST_to_local_time_dateutil_central_timestamp(self) assert table.view().to_dict()["a"] == [d.astimezone(CST).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_CST_to_local_time_dateutil_eastern_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["US/Central"] - } + data = {"a": TZ_TIMESTAMPS["US/Central"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "US/Eastern" @@ -1000,9 +749,7 @@ def test_table_should_convert_CST_to_local_time_dateutil_eastern_timestamp(self) assert table.view().to_dict()["a"] == [d.astimezone(EST).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_EST_to_local_time_dateutil_GMT_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["US/Eastern"] - } + data = {"a": TZ_TIMESTAMPS["US/Eastern"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "GMT" @@ -1012,9 +759,7 @@ def test_table_should_convert_EST_to_local_time_dateutil_GMT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(GMT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_GMT_to_local_time_dateutil_HKT_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["GMT"] - } + data = {"a": TZ_TIMESTAMPS["GMT"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "Asia/Hong_Kong" @@ -1023,9 +768,7 @@ def test_table_should_convert_GMT_to_local_time_dateutil_HKT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(HKT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_HKT_to_local_time_dateutil_JPT_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["Asia/Hong_Kong"] - } + data = {"a": TZ_TIMESTAMPS["Asia/Hong_Kong"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "Asia/Tokyo" @@ -1034,9 +777,7 @@ def test_table_should_convert_HKT_to_local_time_dateutil_JPT_timestamp(self): assert table.view().to_dict()["a"] == [d.astimezone(JPT).replace(tzinfo=None) for d in data["a"]] def test_table_should_convert_JPT_to_local_time_dateutil_ACT_timestamp(self): - data = { - "a": TZ_TIMESTAMPS["Asia/Tokyo"] - } + data = {"a": TZ_TIMESTAMPS["Asia/Tokyo"]} table = Table(pd.DataFrame(data)) os.environ["TZ"] = "Australia/Sydney" @@ -1046,6 +787,7 @@ def test_table_should_convert_JPT_to_local_time_dateutil_ACT_timestamp(self): class TestTableDateTimeRowColumnPaths(object): """Assert correctness of row and column paths in different timezones.""" + def setup_method(self): # To make sure that local times are not changed, set timezone to EST os.environ["TZ"] = "US/Eastern" @@ -1059,10 +801,7 @@ def teardown_method(self): def test_table_group_by_datetime_row_path_local_time_EST(self): """Make sure that string datetimes generated in Python are in local time and not UTC.""" - data = { - "a": LOCAL_DATETIMES, - "b": [i for i in range(len(LOCAL_DATETIMES))] - } + data = {"a": LOCAL_DATETIMES, "b": [i for i in range(len(LOCAL_DATETIMES))]} table = Table(data) @@ -1075,23 +814,20 @@ def test_table_group_by_datetime_row_path_local_time_EST(self): [datetime(2019, 1, 11, 19, 10, 20)], ], "a": [3, 1, 1, 1], - "b": [3, 0, 1, 2] + "b": [3, 0, 1, 2], } def test_table_group_by_datetime_row_path_UTC(self): """Make sure that string datetimes generated in Python are in UTC if the timezone is UTC. - + Set the timezone before creating the table so that the local datetime is in the intended timezone, as this test asserts that paths in the same timezone are not edited to UTC.""" os.environ["TZ"] = "UTC" time.tzset() - data = { - "a": LOCAL_DATETIMES, - "b": [i for i in range(len(LOCAL_DATETIMES))] - } + data = {"a": LOCAL_DATETIMES, "b": [i for i in range(len(LOCAL_DATETIMES))]} table = Table(data) @@ -1104,7 +840,7 @@ def test_table_group_by_datetime_row_path_UTC(self): [datetime(2019, 1, 11, 19, 10, 20)], ], "a": [3, 1, 1, 1], - "b": [3, 0, 1, 2] + "b": [3, 0, 1, 2], } def test_table_group_by_datetime_row_path_CST(self): @@ -1113,10 +849,7 @@ def test_table_group_by_datetime_row_path_CST(self): os.environ["TZ"] = "US/Central" time.tzset() - data = { - "a": LOCAL_DATETIMES, - "b": [i for i in range(len(LOCAL_DATETIMES))] - } + data = {"a": LOCAL_DATETIMES, "b": [i for i in range(len(LOCAL_DATETIMES))]} table = Table(data) @@ -1129,7 +862,7 @@ def test_table_group_by_datetime_row_path_CST(self): [datetime(2019, 1, 11, 19, 10, 20)], ], "a": [3, 1, 1, 1], - "b": [3, 0, 1, 2] + "b": [3, 0, 1, 2], } def test_table_group_by_datetime_row_path_PST(self): @@ -1138,10 +871,7 @@ def test_table_group_by_datetime_row_path_PST(self): os.environ["TZ"] = "US/Pacific" time.tzset() - data = { - "a": LOCAL_DATETIMES, - "b": [i for i in range(len(LOCAL_DATETIMES))] - } + data = {"a": LOCAL_DATETIMES, "b": [i for i in range(len(LOCAL_DATETIMES))]} table = Table(data) @@ -1154,12 +884,13 @@ def test_table_group_by_datetime_row_path_PST(self): [datetime(2019, 1, 11, 19, 10, 20)], ], "a": [3, 1, 1, 1], - "b": [3, 0, 1, 2] + "b": [3, 0, 1, 2], } class TestTableDateTimeExpressions(object): """Assert correctness of datetime-related expressions in different timezones.""" + def setup_method(self): # To make sure that local times are not changed, set timezone to EST os.environ["TZ"] = "US/Eastern" @@ -1171,9 +902,7 @@ def teardown_method(self): time.tzset() def test_table_now_in_EST(self, util): - data = { - "a": LOCAL_DATETIMES - } + data = {"a": LOCAL_DATETIMES} table = Table(data) now = datetime.now() @@ -1188,9 +917,7 @@ def test_table_now_in_CST(self, util): os.environ["TZ"] = "US/Central" time.tzset() - data = { - "a": LOCAL_DATETIMES - } + data = {"a": LOCAL_DATETIMES} table = Table(data) now = datetime.now() @@ -1200,14 +927,12 @@ def test_table_now_in_CST(self, util): for item in result["now()"]: in_range = now - timedelta(seconds=2) < item < now + timedelta(seconds=2) assert in_range is True - + def test_table_now_in_PST(self, util): os.environ["TZ"] = "US/Pacific" time.tzset() - data = { - "a": LOCAL_DATETIMES - } + data = {"a": LOCAL_DATETIMES} table = Table(data) now = datetime.now() @@ -1219,9 +944,7 @@ def test_table_now_in_PST(self, util): assert in_range is True def test_table_hour_of_day_in_EST(self): - data = { - "a": LOCAL_DATETIMES - } + data = {"a": LOCAL_DATETIMES} table = Table(data) view = table.view(expressions=['hour_of_day("a")']) @@ -1232,9 +955,7 @@ def test_table_hour_of_day_in_CST(self): os.environ["TZ"] = "US/Central" time.tzset() - data = { - "a": LOCAL_DATETIMES - } + data = {"a": LOCAL_DATETIMES} table = Table(data) view = table.view(expressions=['hour_of_day("a")']) @@ -1245,9 +966,7 @@ def test_table_hour_of_day_in_PST(self): os.environ["TZ"] = "US/Pacific" time.tzset() - data = { - "a": LOCAL_DATETIMES - } + data = {"a": LOCAL_DATETIMES} table = Table(data) view = table.view(expressions=['hour_of_day("a")']) @@ -1258,9 +977,7 @@ def test_table_day_of_week_edge_in_EST(self): """Make sure edge cases are fixed for day of week - if a local time converted to UTC is in the next day, the day of week computation needs to be in local time.""" - data = { - "a": [datetime(2020, 1, 31, 23, 59)] - } + data = {"a": [datetime(2020, 1, 31, 23, 59)]} table = Table(data) view = table.view(expressions=['day_of_week("a")']) @@ -1271,9 +988,7 @@ def test_table_day_of_week_edge_in_CST(self): os.environ["TZ"] = "US/Central" time.tzset() - data = { - "a": [datetime(2020, 1, 31, 23, 59)] - } + data = {"a": [datetime(2020, 1, 31, 23, 59)]} table = Table(data) view = table.view(expressions=['day_of_week("a")']) @@ -1284,9 +999,7 @@ def test_table_day_of_week_edge_in_PST(self): os.environ["TZ"] = "US/Pacific" time.tzset() - data = { - "a": [datetime(2020, 1, 31, 23, 59)] - } + data = {"a": [datetime(2020, 1, 31, 23, 59)]} table = Table(data) view = table.view(expressions=['day_of_week("a")']) @@ -1297,9 +1010,7 @@ def test_table_month_of_year_edge_in_EST(self): """Make sure edge cases are fixed for month of year - if a local time converted to UTC is in the next month, the month of year computation needs to be in local time.""" - data = { - "a": [datetime(2020, 1, 31, 23, 59)] - } + data = {"a": [datetime(2020, 1, 31, 23, 59)]} table = Table(data) view = table.view(expressions=['month_of_year("a")']) @@ -1310,9 +1021,7 @@ def test_table_month_of_year_edge_in_CST(self): os.environ["TZ"] = "US/Central" time.tzset() - data = { - "a": [datetime(2020, 1, 31, 23, 59)] - } + data = {"a": [datetime(2020, 1, 31, 23, 59)]} table = Table(data) view = table.view(expressions=['month_of_year("a")']) @@ -1323,9 +1032,7 @@ def test_table_month_of_year_edge_in_PST(self): os.environ["TZ"] = "US/Pacific" time.tzset() - data = { - "a": [datetime(2020, 1, 31, 23, 59)] - } + data = {"a": [datetime(2020, 1, 31, 23, 59)]} table = Table(data) view = table.view(expressions=['month_of_year("a")']) @@ -1336,9 +1043,7 @@ def test_table_day_bucket_edge_in_EST(self): """Make sure edge cases are fixed for day_bucket - if a local time converted to UTC is in the next day, the day_bucket computation needs to be in local time.""" - data = { - "a": [datetime(2020, 1, 31, 23, 59)] - } + data = {"a": [datetime(2020, 1, 31, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'D')"]) @@ -1349,9 +1054,7 @@ def test_table_day_bucket_edge_in_CST(self): os.environ["TZ"] = "US/Central" time.tzset() - data = { - "a": [datetime(2020, 1, 31, 23, 59)] - } + data = {"a": [datetime(2020, 1, 31, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'D')"]) @@ -1362,9 +1065,7 @@ def test_table_day_bucket_edge_in_PST(self): os.environ["TZ"] = "US/Pacific" time.tzset() - data = { - "a": [datetime(2020, 1, 31, 23, 59)] - } + data = {"a": [datetime(2020, 1, 31, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'D')"]) @@ -1375,9 +1076,7 @@ def test_table_week_bucket_edge_in_EST(self): """Make sure edge cases are fixed for week_bucket - if a local time converted to UTC is in the next day, the week_bucket computation needs to be in local time.""" - data = { - "a": [datetime(2020, 2, 2, 23, 59)] - } + data = {"a": [datetime(2020, 2, 2, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'W')"]) @@ -1388,9 +1087,7 @@ def test_table_week_bucket_edge_in_CST(self): os.environ["TZ"] = "US/Central" time.tzset() - data = { - "a": [datetime(2020, 2, 2, 23, 59)] - } + data = {"a": [datetime(2020, 2, 2, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'W')"]) @@ -1401,9 +1098,7 @@ def test_table_week_bucket_edge_in_PST(self): os.environ["TZ"] = "US/Pacific" time.tzset() - data = { - "a": [datetime(2020, 2, 2, 23, 59)] - } + data = {"a": [datetime(2020, 2, 2, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'W')"]) @@ -1412,9 +1107,7 @@ def test_table_week_bucket_edge_in_PST(self): def test_table_week_bucket_edge_flip_in_EST(self): """Week bucket should flip backwards to last month.""" - data = { - "a": [datetime(2020, 3, 1, 12, 59)] - } + data = {"a": [datetime(2020, 3, 1, 12, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'W')"]) @@ -1424,9 +1117,7 @@ def test_table_week_bucket_edge_flip_in_EST(self): def test_table_week_bucket_edge_flip_in_CST(self): os.environ["TZ"] = "US/Central" time.tzset() - data = { - "a": [datetime(2020, 3, 1, 12, 59)] - } + data = {"a": [datetime(2020, 3, 1, 12, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'W')"]) @@ -1436,9 +1127,7 @@ def test_table_week_bucket_edge_flip_in_CST(self): def test_table_week_bucket_edge_flip_in_PST(self): os.environ["TZ"] = "US/Pacific" time.tzset() - data = { - "a": [datetime(2020, 3, 1, 12, 59)] - } + data = {"a": [datetime(2020, 3, 1, 12, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'W')"]) @@ -1449,24 +1138,18 @@ def test_table_month_bucket_edge_in_EST(self): """Make sure edge cases are fixed for month_bucket - if a local time converted to UTC is in the next day, the month_bucket computation needs to be in local time.""" - data = { - "a": [datetime(2020, 6, 30, 23, 59)] - } + data = {"a": [datetime(2020, 6, 30, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'M')"]) result = view.to_dict() assert result["bucket(\"a\", 'M')"] == [datetime(2020, 6, 1)] - - def test_table_month_bucket_edge_in_CST(self): os.environ["TZ"] = "US/Central" time.tzset() - data = { - "a": [datetime(2020, 6, 30, 23, 59)] - } + data = {"a": [datetime(2020, 6, 30, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'M')"]) @@ -1477,9 +1160,7 @@ def test_table_month_bucket_edge_in_PST(self): os.environ["TZ"] = "US/Pacific" time.tzset() - data = { - "a": [datetime(2020, 6, 30, 23, 59)] - } + data = {"a": [datetime(2020, 6, 30, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'M')"]) @@ -1490,9 +1171,7 @@ def test_table_year_bucket_edge_in_EST(self): """Make sure edge cases are fixed for year_bucket - if a local time converted to UTC is in the next day, the year_bucket computation needs to be in local time.""" - data = { - "a": [datetime(2019, 12, 31, 23, 59)] - } + data = {"a": [datetime(2019, 12, 31, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'Y')"]) @@ -1502,9 +1181,7 @@ def test_table_year_bucket_edge_in_EST(self): def test_table_year_bucket_edge_in_CST(self): os.environ["TZ"] = "US/Central" time.tzset() - data = { - "a": [datetime(2019, 12, 31, 23, 59)] - } + data = {"a": [datetime(2019, 12, 31, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'Y')"]) @@ -1514,9 +1191,7 @@ def test_table_year_bucket_edge_in_CST(self): def test_table_year_bucket_edge_in_PST(self): os.environ["TZ"] = "US/Pacific" time.tzset() - data = { - "a": [datetime(2019, 12, 31, 23, 59)] - } + data = {"a": [datetime(2019, 12, 31, 23, 59)]} table = Table(data) view = table.view(expressions=["bucket(\"a\", 'Y')"]) @@ -1525,12 +1200,8 @@ def test_table_year_bucket_edge_in_PST(self): class TestTableDateTimePivots(object): - def test_table_group_by_date_correct(self): - data = { - "a": [date(2020, i, 15) for i in range(1, 13)], - "b": [i for i in range(1, 13)] - } + data = {"a": [date(2020, i, 15) for i in range(1, 13)], "b": [i for i in range(1, 13)]} table = Table(data) view = table.view(group_by=["a"]) assert view.to_columns() == { @@ -1547,17 +1218,14 @@ def test_table_group_by_date_correct(self): [datetime(2020, 9, 15, 0, 0)], [datetime(2020, 10, 15, 0, 0)], [datetime(2020, 11, 15, 0, 0)], - [datetime(2020, 12, 15, 0, 0)] + [datetime(2020, 12, 15, 0, 0)], ], "a": [12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - "b": [78, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + "b": [78, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], } def test_table_group_by_pandas_date_correct(self): - data = { - "a": [date(2020, i, 15) for i in range(1, 13)], - "b": [i for i in range(1, 13)] - } + data = {"a": [date(2020, i, 15) for i in range(1, 13)], "b": [i for i in range(1, 13)]} table = Table(pd.DataFrame(data)) view = table.view(group_by=["a"]) assert view.to_columns() == { @@ -1574,605 +1242,71 @@ def test_table_group_by_pandas_date_correct(self): [datetime(2020, 9, 15, 0, 0)], [datetime(2020, 10, 15, 0, 0)], [datetime(2020, 11, 15, 0, 0)], - [datetime(2020, 12, 15, 0, 0)] + [datetime(2020, 12, 15, 0, 0)], ], "index": [66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "a": [12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - "b": [78, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + "b": [78, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], } def test_table_split_by_date_correct(self): - data = { - "a": [date(2020, i, 15) for i in range(1, 13)], - "b": [i for i in range(1, 13)] - } + data = {"a": [date(2020, i, 15) for i in range(1, 13)], "b": [i for i in range(1, 13)]} table = Table(data) view = table.view(split_by=["a"]) assert view.to_columns() == { - '2020-01-15|a': [datetime(2020, 1, 15, 0, 0), - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-01-15|b': [1, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-02-15|a': [None, - datetime(2020, 2, 15, 0, 0), - None, - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-02-15|b': [None, - 2, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-03-15|a': [None, - None, - datetime(2020, 3, 15, 0, 0), - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-03-15|b': [None, - None, - 3, - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-04-15|a': [None, - None, - None, - datetime(2020, 4, 15, 0, 0), - None, - None, - None, - None, - None, - None, - None, - None], - '2020-04-15|b': [None, - None, - None, - 4, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-05-15|a': [None, - None, - None, - None, - datetime(2020, 5, 15, 0, 0), - None, - None, - None, - None, - None, - None, - None], - '2020-05-15|b': [None, - None, - None, - None, - 5, - None, - None, - None, - None, - None, - None, - None], - '2020-06-15|a': [None, - None, - None, - None, - None, - datetime(2020, 6, 15, 0, 0), - None, - None, - None, - None, - None, - None], - '2020-06-15|b': [None, - None, - None, - None, - None, - 6, - None, - None, - None, - None, - None, - None], - '2020-07-15|a': [None, - None, - None, - None, - None, - None, - datetime(2020, 7, 15, 0, 0), - None, - None, - None, - None, - None], - '2020-07-15|b': [None, - None, - None, - None, - None, - None, - 7, - None, - None, - None, - None, - None], - '2020-08-15|a': [None, - None, - None, - None, - None, - None, - None, - datetime(2020, 8, 15, 0, 0), - None, - None, - None, - None], - '2020-08-15|b': [None, - None, - None, - None, - None, - None, - None, - 8, - None, - None, - None, - None], - '2020-09-15|a': [None, - None, - None, - None, - None, - None, - None, - None, - datetime(2020, 9, 15, 0, 0), - None, - None, - None], - '2020-09-15|b': [None, - None, - None, - None, - None, - None, - None, - None, - 9, - None, - None, - None], - '2020-10-15|a': [None, - None, - None, - None, - None, - None, - None, - None, - None, - datetime(2020, 10, 15, 0, 0), - None, - None], - '2020-10-15|b': [None, - None, - None, - None, - None, - None, - None, - None, - None, - 10, - None, - None], - '2020-11-15|a': [None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - datetime(2020, 11, 15, 0, 0), - None], - '2020-11-15|b': [None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - 11, - None], - '2020-12-15|a': [None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - datetime(2020, 12, 15, 0, 0)], - '2020-12-15|b': [None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - 12] + "2020-01-15|a": [datetime(2020, 1, 15, 0, 0), None, None, None, None, None, None, None, None, None, None, None], + "2020-01-15|b": [1, None, None, None, None, None, None, None, None, None, None, None], + "2020-02-15|a": [None, datetime(2020, 2, 15, 0, 0), None, None, None, None, None, None, None, None, None, None], + "2020-02-15|b": [None, 2, None, None, None, None, None, None, None, None, None, None], + "2020-03-15|a": [None, None, datetime(2020, 3, 15, 0, 0), None, None, None, None, None, None, None, None, None], + "2020-03-15|b": [None, None, 3, None, None, None, None, None, None, None, None, None], + "2020-04-15|a": [None, None, None, datetime(2020, 4, 15, 0, 0), None, None, None, None, None, None, None, None], + "2020-04-15|b": [None, None, None, 4, None, None, None, None, None, None, None, None], + "2020-05-15|a": [None, None, None, None, datetime(2020, 5, 15, 0, 0), None, None, None, None, None, None, None], + "2020-05-15|b": [None, None, None, None, 5, None, None, None, None, None, None, None], + "2020-06-15|a": [None, None, None, None, None, datetime(2020, 6, 15, 0, 0), None, None, None, None, None, None], + "2020-06-15|b": [None, None, None, None, None, 6, None, None, None, None, None, None], + "2020-07-15|a": [None, None, None, None, None, None, datetime(2020, 7, 15, 0, 0), None, None, None, None, None], + "2020-07-15|b": [None, None, None, None, None, None, 7, None, None, None, None, None], + "2020-08-15|a": [None, None, None, None, None, None, None, datetime(2020, 8, 15, 0, 0), None, None, None, None], + "2020-08-15|b": [None, None, None, None, None, None, None, 8, None, None, None, None], + "2020-09-15|a": [None, None, None, None, None, None, None, None, datetime(2020, 9, 15, 0, 0), None, None, None], + "2020-09-15|b": [None, None, None, None, None, None, None, None, 9, None, None, None], + "2020-10-15|a": [None, None, None, None, None, None, None, None, None, datetime(2020, 10, 15, 0, 0), None, None], + "2020-10-15|b": [None, None, None, None, None, None, None, None, None, 10, None, None], + "2020-11-15|a": [None, None, None, None, None, None, None, None, None, None, datetime(2020, 11, 15, 0, 0), None], + "2020-11-15|b": [None, None, None, None, None, None, None, None, None, None, 11, None], + "2020-12-15|a": [None, None, None, None, None, None, None, None, None, None, None, datetime(2020, 12, 15, 0, 0)], + "2020-12-15|b": [None, None, None, None, None, None, None, None, None, None, None, 12], } def test_table_split_by_pandas_date_correct(self): - data = { - "a": [date(2020, i, 15) for i in range(1, 13)], - "b": [i for i in range(1, 13)] - } + data = {"a": [date(2020, i, 15) for i in range(1, 13)], "b": [i for i in range(1, 13)]} table = Table(pd.DataFrame(data)) view = table.view(columns=["a", "b"], split_by=["a"]) assert view.to_columns() == { - '2020-01-15|a': [datetime(2020, 1, 15, 0, 0), - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-01-15|b': [1, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-02-15|a': [None, - datetime(2020, 2, 15, 0, 0), - None, - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-02-15|b': [None, - 2, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-03-15|a': [None, - None, - datetime(2020, 3, 15, 0, 0), - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-03-15|b': [None, - None, - 3, - None, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-04-15|a': [None, - None, - None, - datetime(2020, 4, 15, 0, 0), - None, - None, - None, - None, - None, - None, - None, - None], - '2020-04-15|b': [None, - None, - None, - 4, - None, - None, - None, - None, - None, - None, - None, - None], - '2020-05-15|a': [None, - None, - None, - None, - datetime(2020, 5, 15, 0, 0), - None, - None, - None, - None, - None, - None, - None], - '2020-05-15|b': [None, - None, - None, - None, - 5, - None, - None, - None, - None, - None, - None, - None], - '2020-06-15|a': [None, - None, - None, - None, - None, - datetime(2020, 6, 15, 0, 0), - None, - None, - None, - None, - None, - None], - '2020-06-15|b': [None, - None, - None, - None, - None, - 6, - None, - None, - None, - None, - None, - None], - '2020-07-15|a': [None, - None, - None, - None, - None, - None, - datetime(2020, 7, 15, 0, 0), - None, - None, - None, - None, - None], - '2020-07-15|b': [None, - None, - None, - None, - None, - None, - 7, - None, - None, - None, - None, - None], - '2020-08-15|a': [None, - None, - None, - None, - None, - None, - None, - datetime(2020, 8, 15, 0, 0), - None, - None, - None, - None], - '2020-08-15|b': [None, - None, - None, - None, - None, - None, - None, - 8, - None, - None, - None, - None], - '2020-09-15|a': [None, - None, - None, - None, - None, - None, - None, - None, - datetime(2020, 9, 15, 0, 0), - None, - None, - None], - '2020-09-15|b': [None, - None, - None, - None, - None, - None, - None, - None, - 9, - None, - None, - None], - '2020-10-15|a': [None, - None, - None, - None, - None, - None, - None, - None, - None, - datetime(2020, 10, 15, 0, 0), - None, - None], - '2020-10-15|b': [None, - None, - None, - None, - None, - None, - None, - None, - None, - 10, - None, - None], - '2020-11-15|a': [None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - datetime(2020, 11, 15, 0, 0), - None], - '2020-11-15|b': [None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - 11, - None], - '2020-12-15|a': [None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - datetime(2020, 12, 15, 0, 0)], - '2020-12-15|b': [None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - 12] + "2020-01-15|a": [datetime(2020, 1, 15, 0, 0), None, None, None, None, None, None, None, None, None, None, None], + "2020-01-15|b": [1, None, None, None, None, None, None, None, None, None, None, None], + "2020-02-15|a": [None, datetime(2020, 2, 15, 0, 0), None, None, None, None, None, None, None, None, None, None], + "2020-02-15|b": [None, 2, None, None, None, None, None, None, None, None, None, None], + "2020-03-15|a": [None, None, datetime(2020, 3, 15, 0, 0), None, None, None, None, None, None, None, None, None], + "2020-03-15|b": [None, None, 3, None, None, None, None, None, None, None, None, None], + "2020-04-15|a": [None, None, None, datetime(2020, 4, 15, 0, 0), None, None, None, None, None, None, None, None], + "2020-04-15|b": [None, None, None, 4, None, None, None, None, None, None, None, None], + "2020-05-15|a": [None, None, None, None, datetime(2020, 5, 15, 0, 0), None, None, None, None, None, None, None], + "2020-05-15|b": [None, None, None, None, 5, None, None, None, None, None, None, None], + "2020-06-15|a": [None, None, None, None, None, datetime(2020, 6, 15, 0, 0), None, None, None, None, None, None], + "2020-06-15|b": [None, None, None, None, None, 6, None, None, None, None, None, None], + "2020-07-15|a": [None, None, None, None, None, None, datetime(2020, 7, 15, 0, 0), None, None, None, None, None], + "2020-07-15|b": [None, None, None, None, None, None, 7, None, None, None, None, None], + "2020-08-15|a": [None, None, None, None, None, None, None, datetime(2020, 8, 15, 0, 0), None, None, None, None], + "2020-08-15|b": [None, None, None, None, None, None, None, 8, None, None, None, None], + "2020-09-15|a": [None, None, None, None, None, None, None, None, datetime(2020, 9, 15, 0, 0), None, None, None], + "2020-09-15|b": [None, None, None, None, None, None, None, None, 9, None, None, None], + "2020-10-15|a": [None, None, None, None, None, None, None, None, None, datetime(2020, 10, 15, 0, 0), None, None], + "2020-10-15|b": [None, None, None, None, None, None, None, None, None, 10, None, None], + "2020-11-15|a": [None, None, None, None, None, None, None, None, None, None, datetime(2020, 11, 15, 0, 0), None], + "2020-11-15|b": [None, None, None, None, None, None, None, None, None, None, 11, None], + "2020-12-15|a": [None, None, None, None, None, None, None, None, None, None, None, datetime(2020, 12, 15, 0, 0)], + "2020-12-15|b": [None, None, None, None, None, None, None, None, None, None, None, 12], } diff --git a/python/perspective/perspective/tests/table/test_table_infer.py b/python/perspective/perspective/tests/table/test_table_infer.py index 34f51a8684..795ec137fd 100644 --- a/python/perspective/perspective/tests/table/test_table_infer.py +++ b/python/perspective/perspective/tests/table/test_table_infer.py @@ -17,7 +17,6 @@ class TestTableInfer(object): - def test_table_infer_int(self): data = {"a": [None, None, None, None, 1, 0, 1, 1, 1]} tbl = Table(data) @@ -32,38 +31,20 @@ def test_table_infer_bool(self): bool_data = [{"a": True, "b": False}, {"a": True, "b": True}] tbl = Table(bool_data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": bool, - "b": bool - } + assert tbl.schema() == {"a": bool, "b": bool} def test_table_infer_bool_str(self): bool_data = [{"a": "True", "b": "False"}, {"a": "True", "b": "True"}] tbl = Table(bool_data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": bool, - "b": bool - } + assert tbl.schema() == {"a": bool, "b": bool} def test_table_bool_infer_str_all_formats_from_schema(self): - bool_data = [ - {"a": "True", "b": "False"}, - {"a": "t", "b": "f"}, - {"a": "true", "b": "false"}, - {"a": 1, "b": 0}, - {"a": "on", "b": "off"} - ] + bool_data = [{"a": "True", "b": "False"}, {"a": "t", "b": "f"}, {"a": "true", "b": "false"}, {"a": 1, "b": 0}, {"a": "on", "b": "off"}] tbl = Table(bool_data) - assert tbl.schema() == { - "a": bool, - "b": bool - } + assert tbl.schema() == {"a": bool, "b": bool} assert tbl.size() == 5 - assert tbl.view().to_dict() == { - "a": [True, True, True, True, True], - "b": [False, False, False, False, False] - } + assert tbl.view().to_dict() == {"a": [True, True, True, True, True], "b": [False, False, False, False, False]} def test_table_infer_bool(self): data = {"a": [None, None, None, None, True, True, True]} @@ -159,7 +140,7 @@ def test_table_infer_mixed_datetime(self): assert tbl.schema() == {"a": datetime} def test_table_strict_datetime_infer(self): - data = {"a": ['10', '9', '8', '7', '6', '5', '4', '3', '2', '1']} + data = {"a": ["10", "9", "8", "7", "6", "5", "4", "3", "2", "1"]} tbl = Table(data) assert tbl.schema() == {"a": str} diff --git a/python/perspective/perspective/tests/table/test_table_limit.py b/python/perspective/perspective/tests/table/test_table_limit.py index d38ee3146a..99b67f3b75 100644 --- a/python/perspective/perspective/tests/table/test_table_limit.py +++ b/python/perspective/perspective/tests/table/test_table_limit.py @@ -17,14 +17,13 @@ class TestTableInfer(object): - def test_table_limit_wraparound_does_not_respect_partial(self): - t = perspective.Table({'a':float, 'b':float}, limit=3) - t.update([{'a':10}, {'b':1}, {'a':20}, {'a':None,'b':2}]) + t = perspective.Table({"a": float, "b": float}, limit=3) + t.update([{"a": 10}, {"b": 1}, {"a": 20}, {"a": None, "b": 2}]) df = t.view().to_df() - t2 = perspective.Table({'a':float, 'b':float}, limit=3) - t2.update([{'a':10}, {'b':1}, {'a':20}, {'b':2}]) + t2 = perspective.Table({"a": float, "b": float}, limit=3) + t2.update([{"a": 10}, {"b": 1}, {"a": 20}, {"b": 2}]) df2 = t2.view().to_df() assert df.to_dict() == df2.to_dict() diff --git a/python/perspective/perspective/tests/table/test_table_numpy.py b/python/perspective/perspective/tests/table/test_table_numpy.py index 252754a290..7bdf6639d2 100644 --- a/python/perspective/perspective/tests/table/test_table_numpy.py +++ b/python/perspective/perspective/tests/table/test_table_numpy.py @@ -28,10 +28,7 @@ def test_table_int(self): data = {"a": np.array([1, 2, 3]), "b": np.array([4, 5, 6])} tbl = Table(data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [1, 2, 3], - "b": [4, 5, 6] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3], "b": [4, 5, 6]} def test_table_int_lots_of_columns(self): data = { @@ -44,68 +41,43 @@ def test_table_int_lots_of_columns(self): } tbl = Table(data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [1, 2, 3], - "b": [4, 5, 6], - "c": [4, 5, 6], - "d": [4, 5, 6], - "e": [4, 5, 6], - "f": [4, 5, 6] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3], "b": [4, 5, 6], "c": [4, 5, 6], "d": [4, 5, 6], "e": [4, 5, 6], "f": [4, 5, 6]} def test_table_int_with_None(self): data = {"a": np.array([1, 2, 3, None, None]), "b": np.array([4, 5, 6, None, None])} tbl = Table(data) assert tbl.size() == 5 - assert tbl.view().to_dict() == { - "a": [1, 2, 3, None, None], - "b": [4, 5, 6, None, None] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, None, None], "b": [4, 5, 6, None, None]} def test_table_int8(self): data = {"a": np.array([1, 2, 3]).astype(np.int8), "b": np.array([4, 5, 6]).astype(np.int8)} tbl = Table(data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [1, 2, 3], - "b": [4, 5, 6] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3], "b": [4, 5, 6]} def test_table_int16(self): data = {"a": np.array([1, 2, 3]).astype(np.int16), "b": np.array([4, 5, 6]).astype(np.int16)} tbl = Table(data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [1, 2, 3], - "b": [4, 5, 6] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3], "b": [4, 5, 6]} def test_table_int32(self): data = {"a": np.array([1, 2, 3]).astype(np.int32), "b": np.array([4, 5, 6]).astype(np.int32)} tbl = Table(data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [1, 2, 3], - "b": [4, 5, 6] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3], "b": [4, 5, 6]} def test_table_int64(self): data = {"a": np.array([1, 2, 3]).astype(np.int64), "b": np.array([4, 5, 6]).astype(np.int64)} tbl = Table(data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [1, 2, 3], - "b": [4, 5, 6] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3], "b": [4, 5, 6]} def test_table_float(self): data = {"a": np.array([1.1, 2.2]), "b": np.array([3.3, 4.4])} tbl = Table(data) assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "a": [1.1, 2.2], - "b": [3.3, 4.4] - } + assert tbl.view().to_dict() == {"a": [1.1, 2.2], "b": [3.3, 4.4]} def test_table_float32(self): data = {"a": np.array([1.1, 2.2]).astype(np.float32), "b": np.array([3.3, 4.4]).astype(np.float32)} @@ -114,17 +86,14 @@ def test_table_float32(self): assert tbl.view().to_dict() == { # py::cast automatically upcasts to 64-bit float "a": [1.100000023841858, 2.200000047683716], - "b": [3.299999952316284, 4.400000095367432] + "b": [3.299999952316284, 4.400000095367432], } def test_table_float64(self): data = {"a": np.array([1.1, 2.2]).astype(np.float64), "b": np.array([3.3, 4.4]).astype(np.float64)} tbl = Table(data) assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "a": [1.1, 2.2], - "b": [3.3, 4.4] - } + assert tbl.view().to_dict() == {"a": [1.1, 2.2], "b": [3.3, 4.4]} # booleans @@ -132,50 +101,32 @@ def test_table_bool(self): data = {"a": np.array([True, False]), "b": np.array([False, True])} tbl = Table(data) assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "a": [True, False], - "b": [False, True] - } + assert tbl.view().to_dict() == {"a": [True, False], "b": [False, True]} def test_table_bool8(self): data = {"a": np.array([True, False]).astype(np.bool8), "b": np.array([False, True]).astype(np.bool8)} tbl = Table(data) assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "a": [True, False], - "b": [False, True] - } + assert tbl.view().to_dict() == {"a": [True, False], "b": [False, True]} def test_table_bool_with_none(self): data = {"a": np.array([True, False, None, False]), "b": np.array([False, True, None, False])} tbl = Table(data) assert tbl.size() == 4 - assert tbl.view().to_dict() == { - "a": [True, False, None, False], - "b": [False, True, None, False] - } + assert tbl.view().to_dict() == {"a": [True, False, None, False], "b": [False, True, None, False]} def test_table_bool_with_dtype(self): data = {"a": np.array([True, False, False], dtype="?"), "b": np.array([False, True, False], dtype="?")} tbl = Table(data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [True, False, False], - "b": [False, True, False] - } + assert tbl.view().to_dict() == {"a": [True, False, False], "b": [False, True, False]} def test_table_bool_str(self): data = {"a": np.array(["True", "False"]), "b": np.array(["False", "True"])} tbl = Table(data) assert tbl.size() == 2 - assert tbl.schema() == { - "a": bool, - "b": bool - } - assert tbl.view().to_dict() == { - "a": [True, False], - "b": [False, True] - } + assert tbl.schema() == {"a": bool, "b": bool} + assert tbl.view().to_dict() == {"a": [True, False], "b": [False, True]} # strings @@ -183,20 +134,14 @@ def test_table_str_object(self): data = {"a": np.array(["abc", "def"], dtype=object), "b": np.array(["hij", "klm"], dtype=object)} tbl = Table(data) assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "a": ["abc", "def"], - "b": ["hij", "klm"] - } + assert tbl.view().to_dict() == {"a": ["abc", "def"], "b": ["hij", "klm"]} def test_table_str_dtype(self): dtype = "U3" data = {"a": np.array(["abc", "def"], dtype=dtype), "b": np.array(["hij", "klm"], dtype=dtype)} tbl = Table(data) assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "a": ["abc", "def"], - "b": ["hij", "klm"] - } + assert tbl.view().to_dict() == {"a": ["abc", "def"], "b": ["hij", "klm"]} # date and datetime @@ -204,351 +149,181 @@ def test_table_date(self): data = {"a": np.array([date(2019, 7, 11)]), "b": np.array([date(2019, 7, 12)])} tbl = Table(data) assert tbl.size() == 1 - assert tbl.schema() == { - "a": date, - "b": date - } - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11)], - "b": [datetime(2019, 7, 12)] - } + assert tbl.schema() == {"a": date, "b": date} + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11)], "b": [datetime(2019, 7, 12)]} def test_table_np_datetime(self): data = {"a": np.array([datetime(2019, 7, 11, 12, 13)], dtype="datetime64[ns]"), "b": np.array([datetime(2019, 7, 11, 12, 14)], dtype="datetime64[ns]")} tbl = Table(data) assert tbl.size() == 1 - assert tbl.schema() == { - "a": datetime, - "b": datetime - } - assert tbl.view().to_numpy() == { - "a": np.array([datetime(2019, 7, 11, 12, 13)], dtype=object), - "b": np.array([datetime(2019, 7, 11, 12, 14)], dtype=object) - } + assert tbl.schema() == {"a": datetime, "b": datetime} + assert tbl.view().to_numpy() == {"a": np.array([datetime(2019, 7, 11, 12, 13)], dtype=object), "b": np.array([datetime(2019, 7, 11, 12, 14)], dtype=object)} def test_table_np_datetime_mixed_dtype(self): data = {"a": np.array([datetime(2019, 7, 11, 12, 13)], dtype="datetime64[ns]"), "b": np.array([datetime(2019, 7, 11, 12, 14)], dtype=object)} tbl = Table(data) assert tbl.size() == 1 - assert tbl.schema() == { - "a": datetime, - "b": datetime - } - assert tbl.view().to_numpy() == { - "a": np.array([datetime(2019, 7, 11, 12, 13)], dtype=object), - "b": np.array([datetime(2019, 7, 11, 12, 14)], dtype=object) - } + assert tbl.schema() == {"a": datetime, "b": datetime} + assert tbl.view().to_numpy() == {"a": np.array([datetime(2019, 7, 11, 12, 13)], dtype=object), "b": np.array([datetime(2019, 7, 11, 12, 14)], dtype=object)} def test_table_np_datetime_default(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ns]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ns]")}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)]} def test_table_np_datetime_string_dtype(self): data = ["2019/07/11 15:30:05", "2019/07/11 15:30:05"] - tbl = Table({ - "a": np.array(data) - }) + tbl = Table({"a": np.array(data)}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 15, 30, 5), datetime(2019, 7, 11, 15, 30, 5)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 15, 30, 5), datetime(2019, 7, 11, 15, 30, 5)]} def test_table_np_datetime_string_on_schema(self): data = ["2019/07/11 15:30:05", "2019/07/11 15:30:05"] - tbl = Table({ - "a": datetime - }) + tbl = Table({"a": datetime}) tbl.update({"a": data}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 15, 30, 5), datetime(2019, 7, 11, 15, 30, 5)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 15, 30, 5), datetime(2019, 7, 11, 15, 30, 5)]} def test_table_np_datetime_ns(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ns]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ns]")}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)]} def test_table_np_datetime_us(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[us]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[us]")}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)]} def test_table_np_datetime_ms(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ms]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ms]")}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)]} def test_table_np_datetime_s(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[s]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[s]")}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)]} def test_table_np_datetime_m(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[m]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[m]")}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)]} def test_table_np_datetime_h(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[h]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[h]")}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)]} def test_table_np_datetime_D(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[D]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[D]")}) - assert tbl.schema() == { - "a": date - } + assert tbl.schema() == {"a": date} - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 0, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 0, 0)]} def test_table_np_datetime_W(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[W]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[W]")}) - assert tbl.schema() == { - "a": date - } + assert tbl.schema() == {"a": date} - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 0, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 0, 0)]} def test_table_np_datetime_M(self): - tbl = Table({ - "a": np.array([ - datetime(2019, 5, 12, 11, 0), - datetime(2019, 6, 12, 11, 0), - datetime(2019, 7, 12, 11, 0)], - dtype="datetime64[M]") - }) + tbl = Table({"a": np.array([datetime(2019, 5, 12, 11, 0), datetime(2019, 6, 12, 11, 0), datetime(2019, 7, 12, 11, 0)], dtype="datetime64[M]")}) - assert tbl.schema() == { - "a": date - } + assert tbl.schema() == {"a": date} - assert tbl.view().to_dict() == { - "a": [ - datetime(2019, 5, 1, 0, 0), - datetime(2019, 6, 1, 0, 0), - datetime(2019, 7, 1, 0, 0) - ] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 5, 1, 0, 0), datetime(2019, 6, 1, 0, 0), datetime(2019, 7, 1, 0, 0)]} def test_table_np_datetime_Y(self): - tbl = Table({ - "a": np.array([ - datetime(2017, 5, 12, 11, 0), - datetime(2018, 6, 12, 11, 0), - datetime(2019, 7, 12, 11, 0)], - dtype="datetime64[Y]") - }) + tbl = Table({"a": np.array([datetime(2017, 5, 12, 11, 0), datetime(2018, 6, 12, 11, 0), datetime(2019, 7, 12, 11, 0)], dtype="datetime64[Y]")}) - assert tbl.schema() == { - "a": date - } + assert tbl.schema() == {"a": date} - assert tbl.view().to_dict() == { - "a": [ - datetime(2017, 1, 1, 0, 0), - datetime(2018, 1, 1, 0, 0), - datetime(2019, 1, 1, 0, 0) - ] - } + assert tbl.view().to_dict() == {"a": [datetime(2017, 1, 1, 0, 0), datetime(2018, 1, 1, 0, 0), datetime(2019, 1, 1, 0, 0)]} def test_table_np_datetime_ms_nat(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0), np.datetime64("nat")], dtype="datetime64[ms]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0), np.datetime64("nat")], dtype="datetime64[ms]")}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0), None] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0), None]} def test_table_np_datetime_s_nat(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0), np.datetime64("nat")], dtype="datetime64[s]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0), np.datetime64("nat")], dtype="datetime64[s]")}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0), None] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0), None]} def test_table_np_timedelta(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ns]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[ns]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ns]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[ns]")}) - assert tbl.schema() == { - "a": str - } + assert tbl.schema() == {"a": str} - assert tbl.view().to_dict() == { - "a": ["950400000000000 nanoseconds"] - } + assert tbl.view().to_dict() == {"a": ["950400000000000 nanoseconds"]} def test_table_np_timedelta_us(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[us]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[us]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[us]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[us]")}) - assert tbl.schema() == { - "a": str - } + assert tbl.schema() == {"a": str} - assert tbl.view().to_dict() == { - "a": ["950400000000 microseconds"] - } + assert tbl.view().to_dict() == {"a": ["950400000000 microseconds"]} def test_table_np_timedelta_ms(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ms]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[ms]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ms]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[ms]")}) - assert tbl.schema() == { - "a": str - } + assert tbl.schema() == {"a": str} - assert tbl.view().to_dict() == { - "a": ["950400000 milliseconds"] - } + assert tbl.view().to_dict() == {"a": ["950400000 milliseconds"]} def test_table_np_timedelta_s(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[s]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[s]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[s]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[s]")}) - assert tbl.schema() == { - "a": str - } + assert tbl.schema() == {"a": str} - assert tbl.view().to_dict() == { - "a": ["950400 seconds"] - } + assert tbl.view().to_dict() == {"a": ["950400 seconds"]} def test_table_np_timedelta_m(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[m]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[m]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[m]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[m]")}) - assert tbl.schema() == { - "a": str - } + assert tbl.schema() == {"a": str} - assert tbl.view().to_dict() == { - "a": ["15840 minutes"] - } + assert tbl.view().to_dict() == {"a": ["15840 minutes"]} def test_table_np_timedelta_h(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[h]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[h]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[h]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[h]")}) - assert tbl.schema() == { - "a": str - } + assert tbl.schema() == {"a": str} - assert tbl.view().to_dict() == { - "a": ["264 hours"] - } + assert tbl.view().to_dict() == {"a": ["264 hours"]} def test_table_np_timedelta_d(self): - tbl = Table({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[D]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[D]") - }) + tbl = Table({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype="datetime64[D]") - np.array([datetime(2019, 7, 1, 11, 0)], dtype="datetime64[D]")}) - assert tbl.schema() == { - "a": str - } + assert tbl.schema() == {"a": str} - assert tbl.view().to_dict() == { - "a": ["11 days"] - } + assert tbl.view().to_dict() == {"a": ["11 days"]} def test_table_np_timedelta_with_none(self): - tbl = Table({ - "a": np.array([None, datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ns]") - np.array([datetime(2019, 7, 1, 11, 0), None], dtype="datetime64[ns]") - }) + tbl = Table({"a": np.array([None, datetime(2019, 7, 12, 11, 0)], dtype="datetime64[ns]") - np.array([datetime(2019, 7, 1, 11, 0), None], dtype="datetime64[ns]")}) - assert tbl.schema() == { - "a": str - } + assert tbl.schema() == {"a": str} - assert tbl.view().to_dict() == { - "a": [None, None] # two `NaT` values - } + assert tbl.view().to_dict() == {"a": [None, None]} # two `NaT` values def test_table_np_mixed(self): - data = { - "a": np.arange(5), - "b": np.full(5, np.nan), - "c": ["a", "b", "c", "d", "e"] - } + data = {"a": np.arange(5), "b": np.full(5, np.nan), "c": ["a", "b", "c", "d", "e"]} # should not be able to parse mixed dicts of numpy array with list with raises(PerspectiveError): Table(data) def test_table_np_promote(self): - data = { - "a": np.arange(5), - "b": np.full(5, np.nan), - "c": np.array([1, 2, 3, 2147483648, 5]) - } - tbl = Table({ - "a": int, - "b": float, - "c": int - }) + data = {"a": np.arange(5), "b": np.full(5, np.nan), "c": np.array([1, 2, 3, 2147483648, 5])} + tbl = Table({"a": int, "b": float, "c": int}) tbl.update(data) assert tbl.size() == 5 - assert tbl.schema() == { - "a": int, - "b": float, - "c": int - } + assert tbl.schema() == {"a": int, "b": float, "c": int} - assert tbl.view().to_dict() == { - "a": [0, 1, 2, 3, 4], - "b": [None, None, None, None, None], - "c": [1.0, 2.0, 3.0, 2147483648.0, 5.0] - } + assert tbl.view().to_dict() == {"a": [0, 1, 2, 3, 4], "b": [None, None, None, None, None], "c": [1.0, 2.0, 3.0, 2147483648.0, 5.0]} def test_table_np_promote_to_string(self): data = { @@ -568,114 +343,71 @@ def test_table_np_promote_to_string(self): } def test_table_np_implicit_index(self): - data = { - "a": np.array(["a", "b", "c", "d", "e"]), - "b": np.array([1, 2, 3, 4, 5]) - } + data = {"a": np.array(["a", "b", "c", "d", "e"]), "b": np.array([1, 2, 3, 4, 5])} tbl = Table(data) assert tbl.size() == 5 - assert tbl.schema() == { - "a": str, - "b": int - } - tbl.update({ - "__INDEX__": np.array([1, 2, 3, 4]), - "a": np.array(["bb", "cc", "dd", "ee"]) - }) + assert tbl.schema() == {"a": str, "b": int} + tbl.update({"__INDEX__": np.array([1, 2, 3, 4]), "a": np.array(["bb", "cc", "dd", "ee"])}) - assert tbl.view().to_dict() == { - "a": ["a", "bb", "cc", "dd", "ee"], - "b": [1, 2, 3, 4, 5] - } + assert tbl.view().to_dict() == {"a": ["a", "bb", "cc", "dd", "ee"], "b": [1, 2, 3, 4, 5]} # from schema def test_table_numpy_from_schema_int(self): - df = { - "a": np.array([1, None, 2, None, 3, 4]) - } - table = Table({ - "a": int - }) + df = {"a": np.array([1, None, 2, None, 3, 4])} + table = Table({"a": int}) table.update(df) assert table.view().to_dict()["a"] == [1, None, 2, None, 3, 4] def test_table_numpy_from_schema_bool(self): data = [True, False, True, False] - df = { - "a": data - } - table = Table({ - "a": bool - }) + df = {"a": data} + table = Table({"a": bool}) table.update(df) assert table.view().to_dict()["a"] == data def test_table_numpy_from_schema_float(self): data = [1.5, None, 2.5, None, 3.5, 4.5] df = {"a": np.array(data)} - table = Table({ - "a": float - }) + table = Table({"a": float}) table.update(df) assert table.view().to_dict()["a"] == data def test_table_numpy_from_schema_float_all_nan(self): data = [np.nan, np.nan, np.nan, np.nan] df = {"a": np.array(data)} - table = Table({ - "a": float - }) + table = Table({"a": float}) table.update(df) assert table.view().to_dict()["a"] == [None, None, None, None] def test_table_numpy_from_schema_float_to_int(self): data = [None, 1.5, None, 2.5, None, 3.5, 4.5] df = {"a": np.array(data)} - table = Table({ - "a": int - }) + table = Table({"a": int}) table.update(df) # truncates decimal assert table.view().to_dict()["a"] == [None, 1, None, 2, None, 3, 4] def test_table_numpy_from_schema_float_to_int_with_nan(self): df = {"a": np.array([np.nan, 1.5, np.nan, 2.5, np.nan, 3.5, 4.5])} - table = Table({ - "a": int - }) + table = Table({"a": int}) table.update(df) # truncates decimal assert table.view().to_dict()["a"] == [None, 1, None, 2, None, 3, 4] - def test_table_numpy_from_schema_float_to_int_with_nan_partial(self): - df = { - "a": np.array([np.nan, 1.5, np.nan, 2.5, np.nan, 3.5, 4.5]) - } - table = Table({ - "a": int, - "b": int - }) + df = {"a": np.array([np.nan, 1.5, np.nan, 2.5, np.nan, 3.5, 4.5])} + table = Table({"a": int, "b": int}) table.update(df) assert table.size() == 7 # truncates decimal - assert table.view().to_dict() == { - "a": [None, 1, None, 2, None, 3, 4], - "b": [None, None, None, None, None, None, None] - } + assert table.view().to_dict() == {"a": [None, 1, None, 2, None, 3, 4], "b": [None, None, None, None, None, None, None]} def test_table_numpy_from_schema_float_to_int_with_nan_partial_indexed(self): """Assert that the null masking works even when primary keys are being reordered.""" - df = { - "a": np.array([np.nan, 1.5, np.nan, 2.5, np.nan, 3.5, 4.5]), - "b": np.array([1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5]) - } - table = Table({ - "a": int, - "b": int - }, index="b") + df = {"a": np.array([np.nan, 1.5, np.nan, 2.5, np.nan, 3.5, 4.5]), "b": np.array([1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5])} + table = Table({"a": int, "b": int}, index="b") table.update(df) # truncates decimal @@ -684,104 +416,58 @@ def test_table_numpy_from_schema_float_to_int_with_nan_partial_indexed(self): "b": [1, 2, 3, 4, 5, 6, 7], } - table.update(pd.DataFrame({ - "a": [10, 9, 8], - "b": [2, 3, 5] - })) - - assert table.view().to_dict() == { - "a": [None, 10, 9, 2, 8, 3, 4], - "b": [1, 2, 3, 4, 5, 6, 7] - } + table.update(pd.DataFrame({"a": [10, 9, 8], "b": [2, 3, 5]})) - table.update({ - "a": np.array([100, np.nan], dtype=np.float64), - "b": np.array([-1, 6], dtype=np.float64) - }) + assert table.view().to_dict() == {"a": [None, 10, 9, 2, 8, 3, 4], "b": [1, 2, 3, 4, 5, 6, 7]} - assert table.view().to_dict() == { - "a": [100, None, 10, 9, 2, 8, None, 4], - "b": [-1, 1, 2, 3, 4, 5, 6, 7] - } + table.update({"a": np.array([100, np.nan], dtype=np.float64), "b": np.array([-1, 6], dtype=np.float64)}) - table.update({ - "a": np.array([100, 1000, np.nan], dtype=np.float64), - "b": np.array([100, 6, 97], dtype=np.float64) - }) + assert table.view().to_dict() == {"a": [100, None, 10, 9, 2, 8, None, 4], "b": [-1, 1, 2, 3, 4, 5, 6, 7]} - assert table.view().to_dict() == { - "a": [100, None, 10, 9, 2, 8, 1000, 4, None, 100], - "b": [-1, 1, 2, 3, 4, 5, 6, 7, 97, 100] - } + table.update({"a": np.array([100, 1000, np.nan], dtype=np.float64), "b": np.array([100, 6, 97], dtype=np.float64)}) + assert table.view().to_dict() == {"a": [100, None, 10, 9, 2, 8, 1000, 4, None, 100], "b": [-1, 1, 2, 3, 4, 5, 6, 7, 97, 100]} def test_table_numpy_from_schema_int_to_float(self): data = [None, 1, None, 2, None, 3, 4] df = {"a": np.array(data)} - table = Table({ - "a": float - }) + table = Table({"a": float}) table.update(df) assert table.view().to_dict()["a"] == [None, 1.0, None, 2.0, None, 3.0, 4.0] def test_table_numpy_from_schema_date(self): data = [date(2019, 8, 15), None, date(2019, 8, 16)] df = {"a": np.array(data)} - table = Table({ - "a": date - }) + table = Table({"a": date}) table.update(df) assert table.view().to_dict()["a"] == [datetime(2019, 8, 15), None, datetime(2019, 8, 16)] def test_table_numpy_from_schema_datetime(self): data = [datetime(2019, 7, 11, 12, 30, 5), None, datetime(2019, 7, 11, 13, 30, 5), None] df = {"a": np.array(data)} - table = Table({ - "a": datetime - }) + table = Table({"a": datetime}) table.update(df) assert table.view().to_dict()["a"] == data def test_table_numpy_from_schema_datetime_timestamp_s(self, util): data = [util.to_timestamp(datetime(2019, 7, 11, 12, 30, 5)), np.nan, util.to_timestamp(datetime(2019, 7, 11, 13, 30, 5)), np.nan] df = {"a": np.array(data)} - table = Table({ - "a": datetime - }) + table = Table({"a": datetime}) table.update(df) - assert table.view().to_dict()["a"] == [ - datetime(2019, 7, 11, 12, 30, 5), - None, - datetime(2019, 7, 11, 13, 30, 5), - None - ] + assert table.view().to_dict()["a"] == [datetime(2019, 7, 11, 12, 30, 5), None, datetime(2019, 7, 11, 13, 30, 5), None] def test_table_numpy_from_schema_datetime_timestamp_ms(self, util): - data = [ - util.to_timestamp(datetime(2019, 7, 11, 12, 30, 5)) * 1000, - np.nan, - util.to_timestamp(datetime(2019, 7, 11, 13, 30, 5)) * 1000, - np.nan - ] + data = [util.to_timestamp(datetime(2019, 7, 11, 12, 30, 5)) * 1000, np.nan, util.to_timestamp(datetime(2019, 7, 11, 13, 30, 5)) * 1000, np.nan] df = {"a": np.array(data)} - table = Table({ - "a": datetime - }) + table = Table({"a": datetime}) table.update(df) - assert table.view().to_dict()["a"] == [ - datetime(2019, 7, 11, 12, 30, 5), - None, - datetime(2019, 7, 11, 13, 30, 5), - None - ] + assert table.view().to_dict()["a"] == [datetime(2019, 7, 11, 12, 30, 5), None, datetime(2019, 7, 11, 13, 30, 5), None] def test_table_numpy_from_schema_str(self): data = ["a", None, "b", None, "c"] df = {"a": np.array(data)} - table = Table({ - "a": str - }) + table = Table({"a": str}) table.update(df) assert table.view().to_dict()["a"] == data @@ -791,201 +477,106 @@ def test_table_numpy_partial_update(self): data = ["a", None, "b", None, "c"] df = {"a": np.array([1, 2, 3, 4, 5]), "b": np.array(data), "c": np.array(data)} table = Table(df, index="a") - table.update({ - "a": np.array([2, 4, 5]), - "b": np.array(["x", "y", "z"]) - }) - assert table.view().to_dict() == { - "a": [1, 2, 3, 4, 5], - "b": ["a", "x", "b", "y", "z"], - "c": ["a", None, "b", None, "c"] - } + table.update({"a": np.array([2, 4, 5]), "b": np.array(["x", "y", "z"])}) + assert table.view().to_dict() == {"a": [1, 2, 3, 4, 5], "b": ["a", "x", "b", "y", "z"], "c": ["a", None, "b", None, "c"]} def test_table_numpy_partial_update_implicit(self): data = ["a", None, "b", None, "c"] df = {"a": np.array([1, 2, 3, 4, 5]), "b": np.array(data), "c": np.array(data)} table = Table(df) - table.update({ - "__INDEX__": np.array([1, 3, 4]), - "b": np.array(["x", "y", "z"]) - }) - assert table.view().to_dict() == { - "a": [1, 2, 3, 4, 5], - "b": ["a", "x", "b", "y", "z"], - "c": ["a", None, "b", None, "c"] - } + table.update({"__INDEX__": np.array([1, 3, 4]), "b": np.array(["x", "y", "z"])}) + assert table.view().to_dict() == {"a": [1, 2, 3, 4, 5], "b": ["a", "x", "b", "y", "z"], "c": ["a", None, "b", None, "c"]} # structured array def test_table_structured_array(self): - d = np.array([(1.0, 2), (3.0, 4)], dtype=[('x', ' table -> serialized output - df = pd.DataFrame({ - "a": [1, 2, 3, 4], - "b": [1.5, 2.5, 3.5, 4.5], - "c": [np.nan, np.nan, "abc", np.nan], - "d": [None, True, None, False], - "e": [float("nan"), datetime(2019, 7, 11, 12, 30), float("nan"), datetime(2019, 7, 11, 12, 30)] - }) + df = pd.DataFrame( + { + "a": [1, 2, 3, 4], + "b": [1.5, 2.5, 3.5, 4.5], + "c": [np.nan, np.nan, "abc", np.nan], + "d": [None, True, None, False], + "e": [float("nan"), datetime(2019, 7, 11, 12, 30), float("nan"), datetime(2019, 7, 11, 12, 30)], + } + ) t1 = Table(df) out1 = t1.view().to_df() @@ -494,405 +333,245 @@ def test_table_pandas_transitive(self): # dtype=object should have correct inferred types def test_table_pandas_object_to_int(self): - df = pd.DataFrame({ - "a": np.array([1, 2, None, 2, None, 3, 4], dtype=object) - }) + df = pd.DataFrame({"a": np.array([1, 2, None, 2, None, 3, 4], dtype=object)}) table = Table(df) - assert table.schema() == { - "index": int, - "a": int - } + assert table.schema() == {"index": int, "a": int} assert table.view().to_dict()["a"] == [1, 2, None, 2, None, 3, 4] def test_table_pandas_object_to_float(self): - df = pd.DataFrame({ - "a": np.array([None, 1, None, 2, None, 3, 4], dtype=object) - }) + df = pd.DataFrame({"a": np.array([None, 1, None, 2, None, 3, 4], dtype=object)}) table = Table(df) - assert table.schema() == { - "index": int, - "a": int - } + assert table.schema() == {"index": int, "a": int} assert table.view().to_dict()["a"] == [None, 1.0, None, 2.0, None, 3.0, 4.0] def test_table_pandas_object_to_bool(self): - df = pd.DataFrame({ - "a": np.array([True, False, True, False, True, False], dtype=object) - }) + df = pd.DataFrame({"a": np.array([True, False, True, False, True, False], dtype=object)}) table = Table(df) - assert table.schema() == { - "index": int, - "a": bool - } + assert table.schema() == {"index": int, "a": bool} assert table.view().to_dict()["a"] == [True, False, True, False, True, False] def test_table_pandas_object_to_date(self): - df = pd.DataFrame({ - "a": np.array([date(2019, 7, 11), date(2019, 7, 12), None], dtype=object) - }) + df = pd.DataFrame({"a": np.array([date(2019, 7, 11), date(2019, 7, 12), None], dtype=object)}) table = Table(df) - assert table.schema() == { - "index": int, - "a": date - } + assert table.schema() == {"index": int, "a": date} assert table.view().to_dict()["a"] == [datetime(2019, 7, 11), datetime(2019, 7, 12), None] def test_table_pandas_object_to_datetime(self): - df = pd.DataFrame({ - "a": np.array([datetime(2019, 7, 11, 1, 2, 3), datetime(2019, 7, 12, 1, 2, 3), None], dtype=object) - }) + df = pd.DataFrame({"a": np.array([datetime(2019, 7, 11, 1, 2, 3), datetime(2019, 7, 12, 1, 2, 3), None], dtype=object)}) table = Table(df) - assert table.schema() == { - "index": int, - "a": datetime - } + assert table.schema() == {"index": int, "a": datetime} assert table.view().to_dict()["a"] == [datetime(2019, 7, 11, 1, 2, 3), datetime(2019, 7, 12, 1, 2, 3), None] def test_table_pandas_object_to_str(self): - df = pd.DataFrame({ - "a": np.array(["abc", "def", None, "ghi"], dtype=object) - }) + df = pd.DataFrame({"a": np.array(["abc", "def", None, "ghi"], dtype=object)}) table = Table(df) - assert table.schema() == { - "index": int, - "a": str - } + assert table.schema() == {"index": int, "a": str} assert table.view().to_dict()["a"] == ["abc", "def", None, "ghi"] # Type matching def test_table_pandas_update_float_schema_with_int(self): - df = pd.DataFrame({ - "a": [1.5, 2.5, 3.5, 4.5], - "b": [1, 2, 3, 4] - }) + df = pd.DataFrame({"a": [1.5, 2.5, 3.5, 4.5], "b": [1, 2, 3, 4]}) - table = Table({ - "a": float, - "b": float - }) + table = Table({"a": float, "b": float}) table.update(df) - assert table.view().to_dict() == { - "a": [1.5, 2.5, 3.5, 4.5], - "b": [1.0, 2.0, 3.0, 4.0] - } + assert table.view().to_dict() == {"a": [1.5, 2.5, 3.5, 4.5], "b": [1.0, 2.0, 3.0, 4.0]} def test_table_pandas_update_int32_with_int64(self): - df = pd.DataFrame({ - "a": [1, 2, 3, 4] - }) + df = pd.DataFrame({"a": [1, 2, 3, 4]}) - table = Table({ - "a": [1, 2, 3, 4] - }) + table = Table({"a": [1, 2, 3, 4]}) table.update(df) - assert table.view().to_dict() == { - "a": [1, 2, 3, 4, 1, 2, 3, 4] - } + assert table.view().to_dict() == {"a": [1, 2, 3, 4, 1, 2, 3, 4]} def test_table_pandas_update_int64_with_float(self): - df = pd.DataFrame({ - "a": [1.5, 2.5, 3.5, 4.5] - }) + df = pd.DataFrame({"a": [1.5, 2.5, 3.5, 4.5]}) - table = Table(pd.DataFrame({ - "a": [1, 2, 3, 4] - })) + table = Table(pd.DataFrame({"a": [1, 2, 3, 4]})) table.update(df) assert table.view().to_dict()["a"] == [1, 2, 3, 4, 1, 2, 3, 4] def test_table_pandas_update_date_schema_with_datetime(self): - df = pd.DataFrame({ - "a": np.array([date(2019, 7, 11)]) - }) + df = pd.DataFrame({"a": np.array([date(2019, 7, 11)])}) - table = Table({ - "a": date - }) + table = Table({"a": date}) table.update(df) - assert table.schema() == { - "a": date - } + assert table.schema() == {"a": date} - assert table.view().to_dict() == { - "a": [datetime(2019, 7, 11)] - } + assert table.view().to_dict() == {"a": [datetime(2019, 7, 11)]} def test_table_pandas_update_datetime_schema_with_date(self): - df = pd.DataFrame({ - "a": np.array([date(2019, 7, 11)]) - }) + df = pd.DataFrame({"a": np.array([date(2019, 7, 11)])}) - table = Table({ - "a": datetime - }) + table = Table({"a": datetime}) table.update(df) - assert table.schema() == { - "a": datetime - } + assert table.schema() == {"a": datetime} - assert table.view().to_dict() == { - "a": [datetime(2019, 7, 11, 0, 0)] - } + assert table.view().to_dict() == {"a": [datetime(2019, 7, 11, 0, 0)]} # Timestamps def test_table_pandas_timestamp_to_datetime(self): data = [pd.Timestamp("2019-07-11 12:30:05"), None, pd.Timestamp("2019-07-11 13:30:05"), None] - df = pd.DataFrame({ - "a": data - }) + df = pd.DataFrame({"a": data}) table = Table(df) assert table.view().to_dict()["a"] == [datetime(2019, 7, 11, 12, 30, 5), None, datetime(2019, 7, 11, 13, 30, 5), None] def test_table_pandas_timestamp_explicit_dtype(self): data = [pd.Timestamp("2019-07-11 12:30:05"), None, pd.Timestamp("2019-07-11 13:30:05"), None] - df = pd.DataFrame({ - "a": np.array(data, dtype="datetime64[ns]") - }) + df = pd.DataFrame({"a": np.array(data, dtype="datetime64[ns]")}) table = Table(df) assert table.view().to_dict()["a"] == [datetime(2019, 7, 11, 12, 30, 5), None, datetime(2019, 7, 11, 13, 30, 5), None] def test_table_pandas_update_datetime_with_timestamp(self): data = [pd.Timestamp("2019-07-11 12:30:05"), None, pd.Timestamp("2019-07-11 13:30:05"), None] - df = pd.DataFrame({ - "a": data - }) - df2 = pd.DataFrame({ - "a": data - }) + df = pd.DataFrame({"a": data}) + df2 = pd.DataFrame({"a": data}) table = Table(df) table.update(df2) - assert table.view().to_dict()["a"] == [datetime(2019, 7, 11, 12, 30, 5), None, datetime(2019, 7, 11, 13, 30, 5), None, - datetime(2019, 7, 11, 12, 30, 5), None, datetime(2019, 7, 11, 13, 30, 5), None] + assert table.view().to_dict()["a"] == [ + datetime(2019, 7, 11, 12, 30, 5), + None, + datetime(2019, 7, 11, 13, 30, 5), + None, + datetime(2019, 7, 11, 12, 30, 5), + None, + datetime(2019, 7, 11, 13, 30, 5), + None, + ] # NaN/NaT reading def test_table_pandas_nan(self): data = [np.nan, np.nan, np.nan, np.nan] - df = pd.DataFrame({ - "a": data - }) + df = pd.DataFrame({"a": data}) table = Table(df) assert table.view().to_dict()["a"] == [None, None, None, None] def test_table_pandas_int_nan(self): data = [np.nan, 1, np.nan, 2] - df = pd.DataFrame({ - "a": data - }) + df = pd.DataFrame({"a": data}) table = Table(df) assert table.view().to_dict()["a"] == [None, 1, None, 2] def test_table_pandas_float_nan(self): data = [np.nan, 1.5, np.nan, 2.5] - df = pd.DataFrame({ - "a": data - }) + df = pd.DataFrame({"a": data}) table = Table(df) assert table.view().to_dict()["a"] == [None, 1.5, None, 2.5] def test_table_read_nan_int_col(self): data = pd.DataFrame({"str": ["abc", float("nan"), "def"], "int": [np.nan, 1, 2]}) tbl = Table(data) - assert tbl.schema() == { - "index": int, - "str": str, - "int": float # np.nan is float type - ints convert to floats when filled in - } + assert tbl.schema() == {"index": int, "str": str, "int": float} # np.nan is float type - ints convert to floats when filled in assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "index": [0, 1, 2], - "str": ["abc", None, "def"], - "int": [None, 1.0, 2.0] - } + assert tbl.view().to_dict() == {"index": [0, 1, 2], "str": ["abc", None, "def"], "int": [None, 1.0, 2.0]} def test_table_read_nan_float_col(self): data = pd.DataFrame({"str": [float("nan"), "abc", float("nan")], "float": [np.nan, 1.5, 2.5]}) tbl = Table(data) - assert tbl.schema() == { - "index": int, - "str": str, - "float": float # can only promote to string or float - } + assert tbl.schema() == {"index": int, "str": str, "float": float} # can only promote to string or float assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "index": [0, 1, 2], - "str": [None, "abc", None], - "float": [None, 1.5, 2.5] - } + assert tbl.view().to_dict() == {"index": [0, 1, 2], "str": [None, "abc", None], "float": [None, 1.5, 2.5]} def test_table_read_nan_bool_col(self): data = pd.DataFrame({"bool": [np.nan, True, np.nan], "bool2": [False, np.nan, True]}) tbl = Table(data) # if np.nan begins a column, it is inferred as float and then can be promoted. if np.nan is in the values (but not at start), the column type is whatever is inferred. - assert tbl.schema() == { - "index": int, - "bool": str, - "bool2": bool - } + assert tbl.schema() == {"index": int, "bool": str, "bool2": bool} assert tbl.size() == 3 # np.nans are always serialized as None - assert tbl.view().to_dict() == { - "index": [0, 1, 2], - "bool": [None, "True", None], - "bool2": [False, None, True] - } + assert tbl.view().to_dict() == {"index": [0, 1, 2], "bool": [None, "True", None], "bool2": [False, None, True]} def test_table_read_nan_date_col(self): data = pd.DataFrame({"str": ["abc", "def"], "date": [float("nan"), date(2019, 7, 11)]}) tbl = Table(data) - assert tbl.schema() == { - "index": int, - "str": str, - "date": str # can only promote to string or float - } + assert tbl.schema() == {"index": int, "str": str, "date": str} # can only promote to string or float assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "index": [0, 1], - "str": ["abc", "def"], - "date": [None, '2019-07-11'] - } + assert tbl.view().to_dict() == {"index": [0, 1], "str": ["abc", "def"], "date": [None, "2019-07-11"]} def test_table_read_nan_datetime_col(self): data = pd.DataFrame({"str": ["abc", "def"], "datetime": [float("nan"), datetime(2019, 7, 11, 11, 0)]}) tbl = Table(data) - assert tbl.schema() == { - "index": int, - "str": str, - "datetime": datetime # can only promote to string or float - } + assert tbl.schema() == {"index": int, "str": str, "datetime": datetime} # can only promote to string or float assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "index": [0, 1], - "str": ["abc", "def"], - "datetime": [None, datetime(2019, 7, 11, 11, 0)] - } + assert tbl.view().to_dict() == {"index": [0, 1], "str": ["abc", "def"], "datetime": [None, datetime(2019, 7, 11, 11, 0)]} def test_table_read_nat_datetime_col(self): data = pd.DataFrame({"str": ["abc", "def"], "datetime": ["NaT", datetime(2019, 7, 11, 11, 0)]}) # datetime col is `datetime` in pandas<2, `object` in pandas>=2, so convert data.datetime = pd.to_datetime(data.datetime) tbl = Table(data) - assert tbl.schema() == { - "index": int, - "str": str, - "datetime": datetime # can only promote to string or float - } + assert tbl.schema() == {"index": int, "str": str, "datetime": datetime} # can only promote to string or float assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "index": [0, 1], - "str": ["abc", "def"], - "datetime": [None, datetime(2019, 7, 11, 11, 0)] - } + assert tbl.view().to_dict() == {"index": [0, 1], "str": ["abc", "def"], "datetime": [None, datetime(2019, 7, 11, 11, 0)]} def test_table_read_nan_datetime_as_date_col(self): data = pd.DataFrame({"str": ["abc", "def"], "datetime": [float("nan"), datetime(2019, 7, 11)]}) tbl = Table(data) - assert tbl.schema() == { - "index": int, - "str": str, - "datetime": datetime # can only promote to string or float - } + assert tbl.schema() == {"index": int, "str": str, "datetime": datetime} # can only promote to string or float assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "index": [0, 1], - "str": ["abc", "def"], - "datetime": [None, datetime(2019, 7, 11)] - } + assert tbl.view().to_dict() == {"index": [0, 1], "str": ["abc", "def"], "datetime": [None, datetime(2019, 7, 11)]} def test_table_read_nan_datetime_no_seconds(self): data = pd.DataFrame({"str": ["abc", "def"], "datetime": [float("nan"), datetime(2019, 7, 11, 11, 0)]}) tbl = Table(data) - assert tbl.schema() == { - "index": int, - "str": str, - "datetime": datetime # can only promote to string or float - } + assert tbl.schema() == {"index": int, "str": str, "datetime": datetime} # can only promote to string or float assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "index": [0, 1], - "str": ["abc", "def"], - "datetime": [None, datetime(2019, 7, 11, 11, 0)] - } + assert tbl.view().to_dict() == {"index": [0, 1], "str": ["abc", "def"], "datetime": [None, datetime(2019, 7, 11, 11, 0)]} def test_table_read_nan_datetime_milliseconds(self): data = pd.DataFrame({"str": ["abc", "def"], "datetime": [np.nan, datetime(2019, 7, 11, 10, 30, 55)]}) tbl = Table(data) - assert tbl.schema() == { - "index": int, - "str": str, - "datetime": datetime # can only promote to string or float - } + assert tbl.schema() == {"index": int, "str": str, "datetime": datetime} # can only promote to string or float assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "index": [0, 1], - "str": ["abc", "def"], - "datetime": [None, datetime(2019, 7, 11, 10, 30, 55)] - } + assert tbl.view().to_dict() == {"index": [0, 1], "str": ["abc", "def"], "datetime": [None, datetime(2019, 7, 11, 10, 30, 55)]} def test_table_pandas_correct_csv_nan_end(self): s = "str,int\n,1\n,2\nabc,3" csv = StringIO(s) data = pd.read_csv(csv) tbl = Table(data) - assert tbl.schema() == { - "index": int, - "str": str, - "int": int - } + assert tbl.schema() == {"index": int, "str": str, "int": int} assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "index": [0, 1, 2], - "str": [None, None, "abc"], - "int": [1, 2, 3] - } + assert tbl.view().to_dict() == {"index": [0, 1, 2], "str": [None, None, "abc"], "int": [1, 2, 3]} def test_table_pandas_correct_csv_nan_intermittent(self): s = "str,float\nabc,\n,2\nghi," csv = StringIO(s) data = pd.read_csv(csv) tbl = Table(data) - assert tbl.schema() == { - "index": int, - "str": str, - "float": float - } + assert tbl.schema() == {"index": int, "str": str, "float": float} assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "index": [0, 1, 2], - "str": ["abc", None, "ghi"], - "float": [None, 2, None] - } + assert tbl.view().to_dict() == {"index": [0, 1, 2], "str": ["abc", None, "ghi"], "float": [None, 2, None]} def test_table_series(self): import pandas as pd + data = pd.Series([1, 2, 3], name="a") tbl = Table(data) assert tbl.size() == 3 def test_table_indexed_series(self): import pandas as pd + data = pd.Series([1, 2, 3], index=["a", "b", "c"], name="a") tbl = Table(data) - assert tbl.schema() == { - "index": str, - "a": int - } + assert tbl.schema() == {"index": str, "a": int} assert tbl.size() == 3 def test_groupbys(self, superstore): - df_pivoted = superstore.set_index(['Country', 'Region']) + df_pivoted = superstore.set_index(["Country", "Region"]) table = Table(df_pivoted) columns = table.columns() assert table.size() == 100 @@ -900,19 +579,21 @@ def test_groupbys(self, superstore): assert "Region" in columns def test_pivottable(self, superstore): - pt = pd.pivot_table(superstore, values='Discount', index=['Country', 'Region'], columns='Category') + pt = pd.pivot_table(superstore, values="Discount", index=["Country", "Region"], columns="Category") table = Table(pt) columns = table.columns() assert "Country" in columns assert "Region" in columns def test_splitbys(self): - arrays = [np.array(['bar', 'bar', 'bar', 'bar', 'baz', 'baz', 'baz', 'baz', 'foo', 'foo', 'foo', 'foo', 'qux', 'qux', 'qux', 'qux']), - np.array(['one', 'one', 'two', 'two', 'one', 'one', 'two', 'two', 'one', 'one', 'two', 'two', 'one', 'one', 'two', 'two']), - np.array(['X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y'])] + arrays = [ + np.array(["bar", "bar", "bar", "bar", "baz", "baz", "baz", "baz", "foo", "foo", "foo", "foo", "qux", "qux", "qux", "qux"]), + np.array(["one", "one", "two", "two", "one", "one", "two", "two", "one", "one", "two", "two", "one", "one", "two", "two"]), + np.array(["X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y"]), + ] tuples = list(zip(*arrays)) - index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second', 'third']) + index = pd.MultiIndex.from_tuples(tuples, names=["first", "second", "third"]) - df_both = pd.DataFrame(np.random.randn(3, 16), index=['A', 'B', 'C'], columns=index) + df_both = pd.DataFrame(np.random.randn(3, 16), index=["A", "B", "C"], columns=index) table = Table(df_both) assert table.size() == 48 diff --git a/python/perspective/perspective/tests/table/test_to_arrow.py b/python/perspective/perspective/tests/table/test_to_arrow.py index 554df39dd7..d48cab303a 100644 --- a/python/perspective/perspective/tests/table/test_to_arrow.py +++ b/python/perspective/perspective/tests/table/test_to_arrow.py @@ -16,71 +16,42 @@ class TestToArrow(object): - def test_to_arrow_nones_symmetric(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow() tbl2 = Table(arr) assert tbl2.view().to_dict() == data def test_to_arrow_big_numbers_symmetric(self): - data = { - "a": [1, 2, 3, 4], - "b": [1.7976931348623157e+308, 1.7976931348623157e+308, 1.7976931348623157e+308, 1.7976931348623157e+308] - } + data = {"a": [1, 2, 3, 4], "b": [1.7976931348623157e308, 1.7976931348623157e308, 1.7976931348623157e308, 1.7976931348623157e308]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow() tbl2 = Table(arr) assert tbl2.view().to_dict() == data def test_to_arrow_boolean_symmetric(self): - data = { - "a": [True, False, None, False, True, None] - } + data = {"a": [True, False, None, False, True, None]} tbl = Table(data) - assert tbl.schema() == { - "a": bool - } + assert tbl.schema() == {"a": bool} arr = tbl.view().to_arrow() tbl2 = Table(arr) assert tbl2.view().to_dict() == data def test_to_arrow_str_symmetric(self): - data = { - "a": ["a", "b", "c", "d", "e", None] - } + data = {"a": ["a", "b", "c", "d", "e", None]} tbl = Table(data) - assert tbl.schema() == { - "a": str - } + assert tbl.schema() == {"a": str} arr = tbl.view().to_arrow() tbl2 = Table(arr) assert tbl2.view().to_dict() == data def test_to_arrow_str_dict(self): - data = { - "a": ["abcdefg", "abcdefg", "h"], - "b": ["aaa", "bbb", "bbb"], - "c": ["hello", "world", "world"] - } + data = {"a": ["abcdefg", "abcdefg", "h"], "b": ["aaa", "bbb", "bbb"], "c": ["hello", "world", "world"]} tbl = Table(data) - assert tbl.schema() == { - "a": str, - "b": str, - "c": str - } + assert tbl.schema() == {"a": str, "b": str, "c": str} arr = tbl.view().to_arrow() # assert that we are actually generating dict arrays @@ -98,85 +69,51 @@ def test_to_arrow_str_dict(self): assert tbl2.view().to_dict() == data def test_to_arrow_date_symmetric(self): - data = { - "a": [date(2019, 7, 11), date(2016, 2, 29), date(2019, 12, 10)] - } + data = {"a": [date(2019, 7, 11), date(2016, 2, 29), date(2019, 12, 10)]} tbl = Table(data) - assert tbl.schema() == { - "a": date - } + assert tbl.schema() == {"a": date} arr = tbl.view().to_arrow() tbl2 = Table(arr) assert tbl2.schema() == tbl.schema() - assert tbl2.view().to_dict() == { - "a": [datetime(2019, 7, 11), datetime(2016, 2, 29), datetime(2019, 12, 10)] - } + assert tbl2.view().to_dict() == {"a": [datetime(2019, 7, 11), datetime(2016, 2, 29), datetime(2019, 12, 10)]} def test_to_arrow_date_symmetric_january(self): - data = { - "a": [date(2019, 1, 1), date(2016, 1, 1), date(2019, 1, 1)] - } + data = {"a": [date(2019, 1, 1), date(2016, 1, 1), date(2019, 1, 1)]} tbl = Table(data) - assert tbl.schema() == { - "a": date - } + assert tbl.schema() == {"a": date} arr = tbl.view().to_arrow() tbl2 = Table(arr) assert tbl2.schema() == tbl.schema() - assert tbl2.view().to_dict() == { - "a": [datetime(2019, 1, 1), datetime(2016, 1, 1), datetime(2019, 1, 1)] - } + assert tbl2.view().to_dict() == {"a": [datetime(2019, 1, 1), datetime(2016, 1, 1), datetime(2019, 1, 1)]} def test_to_arrow_datetime_symmetric(self): - data = { - "a": [datetime(2019, 7, 11, 12, 30), datetime(2016, 2, 29, 11, 0), datetime(2019, 12, 10, 12, 0)] - } + data = {"a": [datetime(2019, 7, 11, 12, 30), datetime(2016, 2, 29, 11, 0), datetime(2019, 12, 10, 12, 0)]} tbl = Table(data) - assert tbl.schema() == { - "a": datetime - } + assert tbl.schema() == {"a": datetime} arr = tbl.view().to_arrow() tbl2 = Table(arr) assert tbl2.schema() == tbl.schema() - assert tbl2.view().to_dict() == { - "a": [datetime(2019, 7, 11, 12, 30), datetime(2016, 2, 29, 11, 0), datetime(2019, 12, 10, 12, 0)] - } + assert tbl2.view().to_dict() == {"a": [datetime(2019, 7, 11, 12, 30), datetime(2016, 2, 29, 11, 0), datetime(2019, 12, 10, 12, 0)]} def test_to_arrow_one_symmetric(self): - data = { - "a": [1, 2, 3, 4], - "b": ["a", "b", "c", "d"], - "c": [datetime(2019, 7, 11, 12, 0), - datetime(2019, 7, 11, 12, 10), - datetime(2019, 7, 11, 12, 20), - datetime(2019, 7, 11, 12, 30)] - } + data = {"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"], "c": [datetime(2019, 7, 11, 12, 0), datetime(2019, 7, 11, 12, 10), datetime(2019, 7, 11, 12, 20), datetime(2019, 7, 11, 12, 30)]} tbl = Table(data) view = tbl.view(group_by=["a"]) arrow = view.to_arrow() tbl2 = Table(arrow) - assert tbl2.schema() == { - 'a (Group by 1)': int, - "a": int, - "b": int, - "c": int - } + assert tbl2.schema() == {"a (Group by 1)": int, "a": int, "b": int, "c": int} d = view.to_dict() - d['a (Group by 1)'] = [x[0] if len(x) > 0 else None for x in d.pop("__ROW_PATH__")] + d["a (Group by 1)"] = [x[0] if len(x) > 0 else None for x in d.pop("__ROW_PATH__")] assert tbl2.view().to_dict() == d def test_to_arrow_two_symmetric(self): - data = { - "a": [1, 2, 3, 4], - "b": ["hello", "world", "hello2", "world2"], - "c": [datetime(2019, 7, 11, 12, i) for i in range(0, 40, 10)] - } + data = {"a": [1, 2, 3, 4], "b": ["hello", "world", "hello2", "world2"], "c": [datetime(2019, 7, 11, 12, i) for i in range(0, 40, 10)]} tbl = Table(data) view = tbl.view(group_by=["a"], split_by=["b"]) arrow = view.to_arrow() tbl2 = Table(arrow) assert tbl2.schema() == { - 'a (Group by 1)': int, + "a (Group by 1)": int, "hello|a": int, "hello|b": int, "hello|c": int, @@ -191,15 +128,11 @@ def test_to_arrow_two_symmetric(self): "world2|c": int, } d = view.to_dict() - d['a (Group by 1)'] = [x[0] if len(x) > 0 else None for x in d.pop("__ROW_PATH__")] + d["a (Group by 1)"] = [x[0] if len(x) > 0 else None for x in d.pop("__ROW_PATH__")] assert tbl2.view().to_dict() == d def test_to_arrow_column_only_symmetric(self): - data = { - "a": [1, 2, 3, 4], - "b": ["a", "b", "c", "d"], - "c": [datetime(2019, 7, 11, 12, i) for i in range(0, 40, 10)] - } + data = {"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"], "c": [datetime(2019, 7, 11, 12, i) for i in range(0, 40, 10)]} tbl = Table(data) view = tbl.view(split_by=["a"]) arrow = view.to_arrow() @@ -223,291 +156,152 @@ def test_to_arrow_column_only_symmetric(self): # start and end row def test_to_arrow_start_row(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(start_row=3) tbl2 = Table(arr) - assert tbl2.view().to_dict() == { - "a": data["a"][3:], - "b": data["b"][3:] - } + assert tbl2.view().to_dict() == {"a": data["a"][3:], "b": data["b"][3:]} def test_to_arrow_end_row(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(end_row=2) tbl2 = Table(arr) - assert tbl2.view().to_dict() == { - "a": data["a"][:2], - "b": data["b"][:2] - } + assert tbl2.view().to_dict() == {"a": data["a"][:2], "b": data["b"][:2]} def test_to_arrow_start_end_row(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(start_row=2, end_row=3) tbl2 = Table(arr) - assert tbl2.view().to_dict() == { - "a": data["a"][2:3], - "b": data["b"][2:3] - } + assert tbl2.view().to_dict() == {"a": data["a"][2:3], "b": data["b"][2:3]} def test_to_arrow_start_end_row_equiv(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(start_row=2, end_row=2) tbl2 = Table(arr) assert tbl2.view().to_dict() == {} def test_to_arrow_start_row_invalid(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(start_row=-1) tbl2 = Table(arr) assert tbl2.view().to_dict() == data def test_to_arrow_end_row_invalid(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(end_row=6) tbl2 = Table(arr) assert tbl2.view().to_dict() == data def test_to_arrow_start_end_row_invalid(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(start_row=-1, end_row=6) tbl2 = Table(arr) assert tbl2.view().to_dict() == data def test_to_arrow_start_col(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(start_col=1) tbl2 = Table(arr) - assert tbl2.view().to_dict() == { - "b": data["b"] - } + assert tbl2.view().to_dict() == {"b": data["b"]} def test_to_arrow_end_col(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(end_col=1) tbl2 = Table(arr) - assert tbl2.view().to_dict() == { - "a": data["a"] - } + assert tbl2.view().to_dict() == {"a": data["a"]} def test_to_arrow_start_end_col(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None], - "c": [None, 1, None, 2, 3], - "d": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None], "c": [None, 1, None, 2, 3], "d": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float, - "c": int, - "d": float - } + assert tbl.schema() == {"a": int, "b": float, "c": int, "d": float} arr = tbl.view().to_arrow(start_col=1, end_col=3) tbl2 = Table(arr) - assert tbl2.view().to_dict() == { - "b": data["b"], - "c": data["c"] - } + assert tbl2.view().to_dict() == {"b": data["b"], "c": data["c"]} def test_to_arrow_start_col_invalid(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(start_col=-1) tbl2 = Table(arr) assert tbl2.view().to_dict() == data def test_to_arrow_end_col_invalid(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(end_col=6) tbl2 = Table(arr) assert tbl2.view().to_dict() == data def test_to_arrow_start_end_col_invalid(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(start_col=-1, end_col=6) tbl2 = Table(arr) assert tbl2.view().to_dict() == data def test_to_arrow_start_end_col_equiv_row(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } - arr = tbl.view().to_arrow( - start_col=1, end_col=1, start_row=2, end_row=3) + assert tbl.schema() == {"a": int, "b": float} + arr = tbl.view().to_arrow(start_col=1, end_col=1, start_row=2, end_row=3) tbl2 = Table(arr) # start/end col is a range - thus start=end provides no columns assert tbl2.view().to_dict() == {} def test_to_arrow_start_end_col_equiv(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(start_col=1, end_col=1) tbl2 = Table(arr) assert tbl2.view().to_dict() == {} def test_to_arrow_start_end_row_end_col(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} arr = tbl.view().to_arrow(end_col=1, start_row=2, end_row=3) tbl2 = Table(arr) - assert tbl2.view().to_dict() == tbl.view().to_dict( - end_col=1, start_row=2, end_row=3) + assert tbl2.view().to_dict() == tbl.view().to_dict(end_col=1, start_row=2, end_row=3) def test_to_arrow_start_end_col_start_row(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None], - "c": [1.5, 2.5, None, 4.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None], "c": [1.5, 2.5, None, 4.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float, - "c": float - } + assert tbl.schema() == {"a": int, "b": float, "c": float} arr = tbl.view().to_arrow(start_col=1, end_col=2, start_row=2) tbl2 = Table(arr) - assert tbl2.view().to_dict() == tbl.view().to_dict( - start_col=1, end_col=2, start_row=2) + assert tbl2.view().to_dict() == tbl.view().to_dict(start_col=1, end_col=2, start_row=2) def test_to_arrow_start_end_col_end_row(self): - data = { - "a": [None, 1, None, 2, 3], - "b": [1.5, 2.5, None, 3.5, None], - "c": [1.5, 2.5, None, 4.5, None] - } + data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None], "c": [1.5, 2.5, None, 4.5, None]} tbl = Table(data) - assert tbl.schema() == { - "a": int, - "b": float, - "c": float - } + assert tbl.schema() == {"a": int, "b": float, "c": float} arr = tbl.view().to_arrow(start_col=1, end_col=2, end_row=2) tbl2 = Table(arr) - assert tbl2.view().to_dict() == tbl.view().to_dict( - start_col=1, end_col=2, end_row=2) + assert tbl2.view().to_dict() == tbl.view().to_dict(start_col=1, end_col=2, end_row=2) def test_to_arrow_one_mean(self): - data = { - "a": [1, 2, 3, 4], - "b": ["a", "a", "b", "b"] - } + data = {"a": [1, 2, 3, 4], "b": ["a", "a", "b", "b"]} table = Table(data) view = table.view(group_by=["b"], columns=["a"], aggregates={"a": "mean"}) @@ -516,8 +310,5 @@ def test_to_arrow_one_mean(self): table2 = Table(arrow) view2 = table2.view() result = view2.to_columns() - - assert result == { - 'b (Group by 1)': [None, 'a', 'b'], - "a": [2.5, 1.5, 3.5] - } \ No newline at end of file + + assert result == {"b (Group by 1)": [None, "a", "b"], "a": [2.5, 1.5, 3.5]} diff --git a/python/perspective/perspective/tests/table/test_to_format.py b/python/perspective/perspective/tests/table/test_to_format.py index 640c246cb1..36d41bd789 100644 --- a/python/perspective/perspective/tests/table/test_to_format.py +++ b/python/perspective/perspective/tests/table/test_to_format.py @@ -20,11 +20,10 @@ from perspective.table import Table from pytest import mark -IS_WIN = os.name == 'nt' +IS_WIN = os.name == "nt" class TestToFormat(object): - # to_records def test_to_records_int(self): @@ -60,7 +59,7 @@ def test_to_records_date_no_dst(self): data = [{"a": today, "b": "string2"}, {"a": today, "b": "string4"}] tbl = Table(data) view = tbl.view() - assert view.to_records() == [{"a": dt, "b": "string2"}, {"a": dt, "b": "string4"}] + assert view.to_records() == [{"a": dt, "b": "string2"}, {"a": dt, "b": "string4"}] def test_to_records_date_str(self): data = [{"a": "03/11/2019", "b": "string2"}, {"a": "03/12/2019", "b": "string4"}] @@ -120,20 +119,13 @@ def test_to_records_none(self): def test_to_records_one(self): data = [{"a": 1, "b": "string1"}, {"a": 1, "b": "string2"}] tbl = Table(data) - view = tbl.view( - group_by=["a"] - ) - assert view.to_records() == [ - {"__ROW_PATH__": [], "a": 2, "b": 2}, {"__ROW_PATH__": [1], "a": 2, "b": 2} - ] + view = tbl.view(group_by=["a"]) + assert view.to_records() == [{"__ROW_PATH__": [], "a": 2, "b": 2}, {"__ROW_PATH__": [1], "a": 2, "b": 2}] def test_to_records_two(self): data = [{"a": 1, "b": "string1"}, {"a": 1, "b": "string2"}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) + view = tbl.view(group_by=["a"], split_by=["b"]) assert view.to_records() == [ {"__ROW_PATH__": [], "string1|a": 1, "string1|b": 1, "string2|a": 1, "string2|b": 1}, {"__ROW_PATH__": [1], "string1|a": 1, "string1|b": 1, "string2|a": 1, "string2|b": 1}, @@ -142,9 +134,7 @@ def test_to_records_two(self): def test_to_records_column_only(self): data = [{"a": 1, "b": "string1"}, {"a": 1, "b": "string2"}] tbl = Table(data) - view = tbl.view( - split_by=["b"] - ) + view = tbl.view(split_by=["b"]) assert view.to_records() == [ {"string1|a": 1, "string1|b": "string1", "string2|a": None, "string2|b": None}, {"string1|a": None, "string1|b": None, "string2|a": 1, "string2|b": "string2"}, @@ -156,19 +146,13 @@ def test_to_dict_int(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - assert view.to_dict() == { - "a": [1, 3], - "b": [2, 4] - } + assert view.to_dict() == {"a": [1, 3], "b": [2, 4]} def test_to_dict_float(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) view = tbl.view() - assert view.to_dict() == { - "a": [1.5, 3.5], - "b": [2.5, 4.5] - } + assert view.to_dict() == {"a": [1.5, 3.5], "b": [2.5, 4.5]} def test_to_dict_date(self): today = date.today() @@ -176,79 +160,49 @@ def test_to_dict_date(self): data = [{"a": today, "b": 2}, {"a": today, "b": 4}] tbl = Table(data) view = tbl.view() - assert view.to_dict() == { - "a": [dt, dt], - "b": [2, 4] - } + assert view.to_dict() == {"a": [dt, dt], "b": [2, 4]} def test_to_dict_datetime(self): dt = datetime(2019, 3, 15, 20, 30, 59, 6000) data = [{"a": dt, "b": 2}, {"a": dt, "b": 4}] tbl = Table(data) view = tbl.view() - assert view.to_dict() == { - "a": [dt, dt], - "b": [2, 4] - } + assert view.to_dict() == {"a": [dt, dt], "b": [2, 4]} def test_to_dict_bool(self): data = [{"a": True, "b": False}, {"a": True, "b": False}] tbl = Table(data) view = tbl.view() - assert view.to_dict() == { - "a": [True, True], - "b": [False, False] - } + assert view.to_dict() == {"a": [True, True], "b": [False, False]} def test_to_dict_string(self): data = [{"a": "string1", "b": "string2"}, {"a": "string3", "b": "string4"}] tbl = Table(data) view = tbl.view() - assert view.to_dict() == { - "a": ["string1", "string3"], - "b": ["string2", "string4"] - } + assert view.to_dict() == {"a": ["string1", "string3"], "b": ["string2", "string4"]} def test_to_dict_none(self): data = [{"a": None, "b": None}, {"a": None, "b": None}] tbl = Table(data) view = tbl.view() - assert view.to_dict() == { - "a": [None, None], - "b": [None, None] - } + assert view.to_dict() == {"a": [None, None], "b": [None, None]} def test_to_dict_one(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - group_by=["a"] - ) - assert view.to_dict() == { - "__ROW_PATH__": [[], [1]], - "a": [2, 2], - "b": [4, 4] - } + view = tbl.view(group_by=["a"]) + assert view.to_dict() == {"__ROW_PATH__": [[], [1]], "a": [2, 2], "b": [4, 4]} def test_to_dict_two(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) - assert view.to_dict() == { - "__ROW_PATH__": [[], [1]], - "2|a": [2, 2], - "2|b": [4, 4] - } + view = tbl.view(group_by=["a"], split_by=["b"]) + assert view.to_dict() == {"__ROW_PATH__": [[], [1]], "2|a": [2, 2], "2|b": [4, 4]} def test_to_dict_column_only(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - split_by=["b"] - ) + view = tbl.view(split_by=["b"]) assert view.to_dict() == { "2|a": [1, 1], "2|b": [2, 2], @@ -257,31 +211,19 @@ def test_to_dict_column_only(self): def test_to_dict_one_no_columns(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - columns=[] - ) + view = tbl.view(group_by=["a"], columns=[]) assert view.to_dict() == {"__ROW_PATH__": [[], [1]]} def test_to_dict_two_no_columns(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"], - columns=[] - ) - assert view.to_dict() == { - "__ROW_PATH__": [[], [1]] - } + view = tbl.view(group_by=["a"], split_by=["b"], columns=[]) + assert view.to_dict() == {"__ROW_PATH__": [[], [1]]} def test_to_dict_column_only_no_columns(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - split_by=["b"], - columns=[] - ) + view = tbl.view(split_by=["b"], columns=[]) assert view.to_dict() == {} # to_numpy @@ -346,9 +288,7 @@ def test_to_numpy_none(self): def test_to_numpy_one(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - group_by=["a"] - ) + view = tbl.view(group_by=["a"]) v = view.to_numpy() assert np.array_equal(v["__ROW_PATH__"], np.array([[], [1]], dtype="object")) assert np.array_equal(v["a"], np.array([2, 2])) @@ -357,10 +297,7 @@ def test_to_numpy_one(self): def test_to_numpy_two(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) + view = tbl.view(group_by=["a"], split_by=["b"]) v = view.to_numpy() assert np.array_equal(v["__ROW_PATH__"], np.array([[], [1]], dtype="object")) assert np.array_equal(v["2|a"], np.array([2, 2])) @@ -369,9 +306,7 @@ def test_to_numpy_two(self): def test_to_numpy_column_only(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - split_by=["b"] - ) + view = tbl.view(split_by=["b"]) v = view.to_numpy() assert np.array_equal(v["2|a"], np.array([1, 1])) assert np.array_equal(v["2|b"], np.array([2, 2])) @@ -401,116 +336,81 @@ def test_to_records_zero_over_max_row(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) view = tbl.view() - records = view.to_records( - end_row=1000 - ) + records = view.to_records(end_row=1000) assert records == data def test_to_records_one_over_max_row(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) - view = tbl.view( - group_by=["a"] - ) - records = view.to_records( - end_row=1000 - ) - assert records == [ - {'__ROW_PATH__': [], 'a': 5, 'b': 7}, - {'__ROW_PATH__': [1.5], 'a': 1.5, 'b': 2.5}, - {'__ROW_PATH__': [3.5], 'a': 3.5, 'b': 4.5} - ] + view = tbl.view(group_by=["a"]) + records = view.to_records(end_row=1000) + assert records == [{"__ROW_PATH__": [], "a": 5, "b": 7}, {"__ROW_PATH__": [1.5], "a": 1.5, "b": 2.5}, {"__ROW_PATH__": [3.5], "a": 3.5, "b": 4.5}] def test_to_records_two_over_max_row(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) - records = view.to_records( - end_row=1000 - ) + view = tbl.view(group_by=["a"], split_by=["b"]) + records = view.to_records(end_row=1000) assert records == [ - {'2|a': 1, '2|b': 2, '4|a': 3, '4|b': 4, '__ROW_PATH__': []}, - {'2|a': 1, '2|b': 2, '4|a': None, '4|b': None, '__ROW_PATH__': [1]}, - {'2|a': None, '2|b': None, '4|a': 3, '4|b': 4, '__ROW_PATH__': [3]} + {"2|a": 1, "2|b": 2, "4|a": 3, "4|b": 4, "__ROW_PATH__": []}, + {"2|a": 1, "2|b": 2, "4|a": None, "4|b": None, "__ROW_PATH__": [1]}, + {"2|a": None, "2|b": None, "4|a": 3, "4|b": 4, "__ROW_PATH__": [3]}, ] def test_to_records_start_row(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_row=1 - ) + records = view.to_records(start_row=1) assert records == [{"a": 3, "b": 4}] def test_to_records_end_row(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - records = view.to_records( - end_row=1 - ) + records = view.to_records(end_row=1) assert records == [{"a": 1, "b": 2}] def test_to_records_start_row_end_row(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_row=1, - end_row=2 - ) + records = view.to_records(start_row=1, end_row=2) assert records == [{"a": 3, "b": 4}] def test_to_records_start_row_end_row_equiv(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_row=1, - end_row=1 - ) + records = view.to_records(start_row=1, end_row=1) assert records == [] def test_to_records_floor_start_row(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_row=1.5 - ) + records = view.to_records(start_row=1.5) assert records == [{"a": 3, "b": 4}] def test_to_records_ceil_end_row(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - records = view.to_records( - end_row=0.5 - ) + records = view.to_records(end_row=0.5) assert records == [{"a": 1, "b": 2}] def test_to_records_floor_start_row_ceil_end_row(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_row=1.5, - end_row=1.5 - ) + records = view.to_records(start_row=1.5, end_row=1.5) assert records == [{"a": 3, "b": 4}] def test_to_records_floor_start_row_ceil_end_row_equiv(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_row=1.5, - end_row=0.5 - ) + records = view.to_records(start_row=1.5, end_row=0.5) assert records == [] # start_col/end_col @@ -519,263 +419,148 @@ def test_to_records_zero_over_max_col(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) view = tbl.view() - records = view.to_records( - end_col=1000 - ) + records = view.to_records(end_col=1000) assert records == data def test_to_records_zero_start_gt_end_col(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_col=2, - end_col=1 - ) + records = view.to_records(start_col=2, end_col=1) assert records == [{}, {}] def test_to_records_zero_start_eq_end_col(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_col=1, - end_col=1 - ) + records = view.to_records(start_col=1, end_col=1) assert records == [{}, {}] def test_to_records_one_over_max_col(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) - view = tbl.view( - group_by=["a"] - ) - records = view.to_records( - end_col=1000 - ) - assert records == [ - {'__ROW_PATH__': [], 'a': 5, 'b': 7}, - {'__ROW_PATH__': [1.5], 'a': 1.5, 'b': 2.5}, - {'__ROW_PATH__': [3.5], 'a': 3.5, 'b': 4.5} - ] + view = tbl.view(group_by=["a"]) + records = view.to_records(end_col=1000) + assert records == [{"__ROW_PATH__": [], "a": 5, "b": 7}, {"__ROW_PATH__": [1.5], "a": 1.5, "b": 2.5}, {"__ROW_PATH__": [3.5], "a": 3.5, "b": 4.5}] def test_to_records_one_start_gt_end_col(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) - view = tbl.view( - group_by=["a"] - ) - records = view.to_records( - start_col=2, - end_col=1 - ) + view = tbl.view(group_by=["a"]) + records = view.to_records(start_col=2, end_col=1) assert records == [{}, {}, {}] def test_to_records_one_start_gt_end_col_large(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) - view = tbl.view( - group_by=["a"] - ) - records = view.to_records( - start_col=20, - end_col=19 - ) + view = tbl.view(group_by=["a"]) + records = view.to_records(start_col=20, end_col=19) assert records == [{}, {}, {}] def test_to_records_one_start_eq_end_col(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) - view = tbl.view( - group_by=["a"] - ) - records = view.to_records( - start_col=0, - end_col=0 - ) - assert records == [{'__ROW_PATH__': []}, {'__ROW_PATH__': [1.5]}, {'__ROW_PATH__': [3.5]}] + view = tbl.view(group_by=["a"]) + records = view.to_records(start_col=0, end_col=0) + assert records == [{"__ROW_PATH__": []}, {"__ROW_PATH__": [1.5]}, {"__ROW_PATH__": [3.5]}] def test_to_records_two_over_max_col(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) - records = view.to_records( - end_col=1000 - ) + view = tbl.view(group_by=["a"], split_by=["b"]) + records = view.to_records(end_col=1000) assert records == [ - {'2|a': 1, '2|b': 2, '4|a': 3, '4|b': 4, '__ROW_PATH__': []}, - {'2|a': 1, '2|b': 2, '4|a': None, '4|b': None, '__ROW_PATH__': [1]}, - {'2|a': None, '2|b': None, '4|a': 3, '4|b': 4, '__ROW_PATH__': [3]} + {"2|a": 1, "2|b": 2, "4|a": 3, "4|b": 4, "__ROW_PATH__": []}, + {"2|a": 1, "2|b": 2, "4|a": None, "4|b": None, "__ROW_PATH__": [1]}, + {"2|a": None, "2|b": None, "4|a": 3, "4|b": 4, "__ROW_PATH__": [3]}, ] def test_to_records_start_col(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_col=1 - ) + records = view.to_records(start_col=1) assert records == [{"b": 2}, {"b": 4}] def test_to_records_end_col(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - records = view.to_records( - end_col=1 - ) + records = view.to_records(end_col=1) assert records == [{"a": 1}, {"a": 3}] def test_to_records_two_end_col(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) - records = view.to_records( - end_row=12, - end_col=5 - ) + view = tbl.view(group_by=["a"], split_by=["b"]) + records = view.to_records(end_row=12, end_col=5) assert records == [ - {'2|a': 1, '2|b': 2, '4|a': 3, '4|b': 4, '__ROW_PATH__': []}, - {'2|a': 1, '2|b': 2, '4|a': None, '4|b': None, '__ROW_PATH__': [1]}, - {'2|a': None, '2|b': None, '4|a': 3, '4|b': 4, '__ROW_PATH__': [3]} + {"2|a": 1, "2|b": 2, "4|a": 3, "4|b": 4, "__ROW_PATH__": []}, + {"2|a": 1, "2|b": 2, "4|a": None, "4|b": None, "__ROW_PATH__": [1]}, + {"2|a": None, "2|b": None, "4|a": 3, "4|b": 4, "__ROW_PATH__": [3]}, ] def test_to_records_two_start_gt_end_col(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) - records = view.to_records( - end_row=12, - start_col=5, - end_col=4 - ) + view = tbl.view(group_by=["a"], split_by=["b"]) + records = view.to_records(end_row=12, start_col=5, end_col=4) assert records == [{}, {}, {}] def test_to_records_two_start_gt_end_col_large_overage(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) - records = view.to_records( - end_row=12, - start_col=50, - end_col=49 - ) + view = tbl.view(group_by=["a"], split_by=["b"]) + records = view.to_records(end_row=12, start_col=50, end_col=49) assert records == [{}, {}, {}] def test_to_records_two_start_end_col_equiv(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) - records = view.to_records( - end_row=12, - start_col=5, - end_col=5 - ) + view = tbl.view(group_by=["a"], split_by=["b"]) + records = view.to_records(end_row=12, start_col=5, end_col=5) assert records == [{}, {}, {}] - def test_to_records_two_sorted_start_gt_end_col(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"], - sort=[["a", "desc"]] - ) - records = view.to_records( - end_row=12, - start_col=5, - end_col=4 - ) + view = tbl.view(group_by=["a"], split_by=["b"], sort=[["a", "desc"]]) + records = view.to_records(end_row=12, start_col=5, end_col=4) assert records == [{}, {}, {}] def test_to_records_two_sorted_start_gt_end_col_large_overage(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"], - sort=[["a", "desc"]] - ) - records = view.to_records( - end_row=12, - start_col=20, - end_col=30 - ) + view = tbl.view(group_by=["a"], split_by=["b"], sort=[["a", "desc"]]) + records = view.to_records(end_row=12, start_col=20, end_col=30) assert records == [{}, {}, {}] def test_to_records_two_sorted_start_gt_end_col_overage(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - columns=[], - group_by=["a"], - split_by=["b"], - sort=[["a", "desc"]] - ) - records = view.to_records( - end_row=12, - start_col=1, - end_col=3 - ) + view = tbl.view(columns=[], group_by=["a"], split_by=["b"], sort=[["a", "desc"]]) + records = view.to_records(end_row=12, start_col=1, end_col=3) assert records == [{}, {}, {}] def test_to_records_two_sorted_start_end_col(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"], - sort=[["a", "desc"]] - ) - records = view.to_records( - start_col=1, - end_col=2 - ) - assert records == [ - {'2|b': 2, '__ROW_PATH__': []}, - {'2|b': None, '__ROW_PATH__': [3]}, - {'2|b': 2, '__ROW_PATH__': [1]} - ] + view = tbl.view(group_by=["a"], split_by=["b"], sort=[["a", "desc"]]) + records = view.to_records(start_col=1, end_col=2) + assert records == [{"2|b": 2, "__ROW_PATH__": []}, {"2|b": None, "__ROW_PATH__": [3]}, {"2|b": 2, "__ROW_PATH__": [1]}] def test_to_records_two_sorted_start_end_col_equiv(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"], - sort=[["a", "desc"]] - ) - records = view.to_records( - end_row=12, - start_col=5, - end_col=5 - ) + view = tbl.view(group_by=["a"], split_by=["b"], sort=[["a", "desc"]]) + records = view.to_records(end_row=12, start_col=5, end_col=5) assert records == [{}, {}, {}] def test_to_records_start_col_end_col(self): data = [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4, "c": 5}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_col=1, - end_col=2 - ) + records = view.to_records(start_col=1, end_col=2) # start_col and end_col access columns at that index - dict key order not guaranteed in python2 assert records == [{"b": 2}, {"b": 4}] @@ -783,55 +568,39 @@ def test_to_records_start_col_end_col_equiv(self): data = [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4, "c": 5}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_col=1, - end_col=1 - ) + records = view.to_records(start_col=1, end_col=1) assert records == [{}, {}] def test_to_records_floor_start_col(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_col=1.5 - ) + records = view.to_records(start_col=1.5) assert records == [{"b": 2}, {"b": 4}] def test_to_records_ceil_end_col(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - records = view.to_records( - end_col=1 - ) + records = view.to_records(end_col=1) assert records == [{"a": 1}, {"a": 3}] def test_to_records_two_ceil_end_col(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) - records = view.to_records( - end_row=12, - end_col=4.5 - ) + view = tbl.view(group_by=["a"], split_by=["b"]) + records = view.to_records(end_row=12, end_col=4.5) assert records == [ - {'2|a': 1, '2|b': 2, '4|a': 3, '4|b': 4, '__ROW_PATH__': []}, - {'2|a': 1, '2|b': 2, '4|a': None, '4|b': None, '__ROW_PATH__': [1]}, - {'2|a': None, '2|b': None, '4|a': 3, '4|b': 4, '__ROW_PATH__': [3]} + {"2|a": 1, "2|b": 2, "4|a": 3, "4|b": 4, "__ROW_PATH__": []}, + {"2|a": 1, "2|b": 2, "4|a": None, "4|b": None, "__ROW_PATH__": [1]}, + {"2|a": None, "2|b": None, "4|a": 3, "4|b": 4, "__ROW_PATH__": [3]}, ] def test_to_records_floor_start_col_ceil_end_col(self): data = [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4, "c": 5}] tbl = Table(data) view = tbl.view() - records = view.to_records( - start_col=1.5, - end_col=1.5 - ) + records = view.to_records(start_col=1.5, end_col=1.5) # start_col and end_col access columns at that index - dict key order not guaranteed in python2 assert records == [{"b": 2}, {"b": 4}] @@ -839,14 +608,8 @@ def test_to_dict_start_col_end_col(self): data = [{"a": 1, "b": 2, "c": 3, "d": 4}, {"a": 3, "b": 4, "c": 5, "d": 6}] tbl = Table(data) view = tbl.view() - d = view.to_dict( - start_col=1, - end_col=3 - ) - assert d == { - "b": [2, 4], - "c": [3, 5] - } + d = view.to_dict(start_col=1, end_col=3) + assert d == {"b": [2, 4], "c": [3, 5]} # to csv @@ -925,56 +688,39 @@ def test_to_csv_custom_rows_cols(self): def test_to_csv_one(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - group_by=["a"] - ) + view = tbl.view(group_by=["a"]) assert view.to_csv() == '"a (Group by 1)","a","b"\n,2,4\n1,2,4\n' def test_to_csv_two(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"] - ) + view = tbl.view(group_by=["a"], split_by=["b"]) assert view.to_csv() == '"a (Group by 1)","2|a","2|b"\n,2,4\n1,2,4\n' def test_to_csv_column_only(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - split_by=["b"] - ) + view = tbl.view(split_by=["b"]) assert view.to_csv() == '"2|a","2|b"\n1,2\n1,2\n' def test_to_csv_one_no_columns(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - columns=[] - ) + view = tbl.view(group_by=["a"], columns=[]) assert view.to_csv() == '"a (Group by 1)"\n\n1\n' def test_to_csv_two_no_columns(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"], - columns=[] - ) + view = tbl.view(group_by=["a"], split_by=["b"], columns=[]) assert view.to_csv() == '"a (Group by 1)"\n\n1\n' def test_to_csv_column_only_no_columns(self): data = [{"a": 1, "b": 2}, {"a": 1, "b": 2}] tbl = Table(data) - view = tbl.view( - split_by=["b"], - columns=[] - ) + view = tbl.view(split_by=["b"], columns=[]) - assert view.to_csv() == '' + assert view.to_csv() == "" # implicit index @@ -982,51 +728,37 @@ def test_to_format_implicit_index_records(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) view = tbl.view() - assert view.to_records(index=True) == [ - {"__INDEX__": [0], "a": 1.5, "b": 2.5}, - {"__INDEX__": [1], "a": 3.5, "b": 4.5} - ] + assert view.to_records(index=True) == [{"__INDEX__": [0], "a": 1.5, "b": 2.5}, {"__INDEX__": [1], "a": 3.5, "b": 4.5}] def test_to_format_implicit_index_dict(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) view = tbl.view() - assert view.to_dict(index=True) == { - "__INDEX__": [[0], [1]], - "a": [1.5, 3.5], - "b": [2.5, 4.5] - } + assert view.to_dict(index=True) == {"__INDEX__": [[0], [1]], "a": [1.5, 3.5], "b": [2.5, 4.5]} def test_to_format_implicit_id_records(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) view = tbl.view() - assert view.to_records(id=True) == [ - {"__ID__": [0], "a": 1.5, "b": 2.5}, - {"__ID__": [1], "a": 3.5, "b": 4.5} - ] + assert view.to_records(id=True) == [{"__ID__": [0], "a": 1.5, "b": 2.5}, {"__ID__": [1], "a": 3.5, "b": 4.5}] def test_to_format_implicit_id_dict(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) view = tbl.view() - assert view.to_dict(id=True) == { - "__ID__": [[0], [1]], - "a": [1.5, 3.5], - "b": [2.5, 4.5] - } + assert view.to_dict(id=True) == {"__ID__": [[0], [1]], "a": [1.5, 3.5], "b": [2.5, 4.5]} def test_to_format_implicit_index_two_dict(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data) view = tbl.view(group_by=["a"], split_by=["b"]) assert view.to_dict(index=True) == { - '2.5|a': [1.5, 1.5, None], - '2.5|b': [2.5, 2.5, None], - '4.5|a': [3.5, None, 3.5], - '4.5|b': [4.5, None, 4.5], - '__INDEX__': [[], [], []], # index needs to be the same length as each column - '__ROW_PATH__': [[], [1.5], [3.5]] + "2.5|a": [1.5, 1.5, None], + "2.5|b": [2.5, 2.5, None], + "4.5|a": [3.5, None, 3.5], + "4.5|b": [4.5, None, 4.5], + "__INDEX__": [[], [], []], # index needs to be the same length as each column + "__ROW_PATH__": [[], [1.5], [3.5]], } def test_to_format_implicit_index_two_dict(self): @@ -1034,12 +766,12 @@ def test_to_format_implicit_index_two_dict(self): tbl = Table(data) view = tbl.view(group_by=["a"], split_by=["b"]) assert view.to_dict(id=True) == { - '2.5|a': [1.5, 1.5, None], - '2.5|b': [2.5, 2.5, None], - '4.5|a': [3.5, None, 3.5], - '4.5|b': [4.5, None, 4.5], - '__ID__': [[], [1.5], [3.5]], # index needs to be the same length as each column - '__ROW_PATH__': [[], [1.5], [3.5]] + "2.5|a": [1.5, 1.5, None], + "2.5|b": [2.5, 2.5, None], + "4.5|a": [3.5, None, 3.5], + "4.5|b": [4.5, None, 4.5], + "__ID__": [[], [1.5], [3.5]], # index needs to be the same length as each column + "__ROW_PATH__": [[], [1.5], [3.5]], } def test_to_format_implicit_index_np(self): @@ -1053,20 +785,13 @@ def test_to_format_explicit_index_records(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data, index="a") view = tbl.view() - assert view.to_records(index=True) == [ - {"__INDEX__": [1.5], "a": 1.5, "b": 2.5}, - {"__INDEX__": [3.5], "a": 3.5, "b": 4.5} - ] + assert view.to_records(index=True) == [{"__INDEX__": [1.5], "a": 1.5, "b": 2.5}, {"__INDEX__": [3.5], "a": 3.5, "b": 4.5}] def test_to_format_explicit_index_dict(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] tbl = Table(data, index="a") view = tbl.view() - assert view.to_dict(index=True) == { - "__INDEX__": [[1.5], [3.5]], - "a": [1.5, 3.5], - "b": [2.5, 4.5] - } + assert view.to_dict(index=True) == {"__INDEX__": [[1.5], [3.5]], "a": [1.5, 3.5], "b": [2.5, 4.5]} def test_to_format_explicit_index_np(self): data = [{"a": 1.5, "b": 2.5}, {"a": 3.5, "b": 4.5}] @@ -1079,10 +804,7 @@ def test_to_format_explicit_index_str_records(self): data = [{"a": "a", "b": 2.5}, {"a": "b", "b": 4.5}] tbl = Table(data, index="a") view = tbl.view() - assert view.to_records(index=True) == [ - {"__INDEX__": ["a"], "a": "a", "b": 2.5}, - {"__INDEX__": ["b"], "a": "b", "b": 4.5} - ] + assert view.to_records(index=True) == [{"__INDEX__": ["a"], "a": "a", "b": 2.5}, {"__INDEX__": ["b"], "a": "b", "b": 4.5}] def test_to_format_explicit_index_datetime_records(self): data = [{"a": datetime(2019, 7, 11, 9, 0), "b": 2.5}, {"a": datetime(2019, 7, 11, 9, 1), "b": 4.5}] @@ -1090,5 +812,5 @@ def test_to_format_explicit_index_datetime_records(self): view = tbl.view() assert view.to_records(index=True) == [ {"__INDEX__": [datetime(2019, 7, 11, 9, 0)], "a": datetime(2019, 7, 11, 9, 0), "b": 2.5}, - {"__INDEX__": [datetime(2019, 7, 11, 9, 1)], "a": datetime(2019, 7, 11, 9, 1), "b": 4.5} + {"__INDEX__": [datetime(2019, 7, 11, 9, 1)], "a": datetime(2019, 7, 11, 9, 1), "b": 4.5}, ] diff --git a/python/perspective/perspective/tests/table/test_update.py b/python/perspective/perspective/tests/table/test_update.py index 3214e70347..ebf059b3bc 100644 --- a/python/perspective/perspective/tests/table/test_update.py +++ b/python/perspective/perspective/tests/table/test_update.py @@ -31,9 +31,7 @@ def test_update_with_missing_or_null_values(self): # write arrow to stream stream = pa.BufferOutputStream() - writer = pa.RecordBatchStreamWriter( - stream, arrow_table.schema, use_legacy_format=False - ) + writer = pa.RecordBatchStreamWriter(stream, arrow_table.schema, use_legacy_format=False) writer.write_table(arrow_table) writer.close() arrow = stream.getvalue().to_pybytes() @@ -43,57 +41,34 @@ def test_update_with_missing_or_null_values(self): assert tbl.view().to_records() == [{"a": "1", "b": ""}, {"a": "3", "b": "4"}] def test_update_from_schema(self): - tbl = Table({ - "a": str, - "b": int - }) + tbl = Table({"a": str, "b": int}) tbl.update([{"a": "abc", "b": 123}]) assert tbl.view().to_records() == [{"a": "abc", "b": 123}] def test_update_columnar_from_schema(self): - tbl = Table({ - "a": str, - "b": int - }) + tbl = Table({"a": str, "b": int}) tbl.update({"a": ["abc"], "b": [123]}) assert tbl.view().to_records() == [{"a": "abc", "b": 123}] def test_update_csv(self): - tbl = Table({ - "a": str, - "b": int - }) + tbl = Table({"a": str, "b": int}) view = tbl.view() tbl.update("a,b\nxyz,123\ndef,100000000") - assert view.to_dict() == { - "a": ["xyz", "def"], - "b": [123, 100000000] - } + assert view.to_dict() == {"a": ["xyz", "def"], "b": [123, 100000000]} def test_update_csv_indexed(self): - tbl = Table({ - "a": str, - "b": float - }, index="a") + tbl = Table({"a": str, "b": float}, index="a") view = tbl.view() tbl.update("a,b\nxyz,1.23456718\ndef,100000000.1") - assert view.to_dict() == { - "a": ["def", "xyz"], - "b": [100000000.1, 1.23456718] - } + assert view.to_dict() == {"a": ["def", "xyz"], "b": [100000000.1, 1.23456718]} tbl.update("a,b\nxyz,0.00000001\ndef,1234.5678\nefg,100.2") - assert view.to_dict() == { - "a": ["def", "efg", "xyz"], - "b": [1234.5678, 100.2, 0.00000001] - } - - + assert view.to_dict() == {"a": ["def", "efg", "xyz"], "b": [1234.5678, 100.2, 0.00000001]} def test_update_append(self): tbl = Table([{"a": "abc", "b": 123}]) @@ -123,10 +98,7 @@ def test_update_partial_unset(self): def test_update_columnar_partial_add_row(self): tbl = Table([{"a": "abc", "b": 123}], index="a") - tbl.update({ - "a": ["abc", "def"], - "b": [456, None] - }) + tbl.update({"a": ["abc", "def"], "b": [456, None]}) assert tbl.view().to_records() == [{"a": "abc", "b": 456}, {"a": "def", "b": None}] @@ -134,20 +106,14 @@ def test_update_columnar_partial_noop(self): tbl = Table([{"a": "abc", "b": 1, "c": 2}], index="a") # no-op because "c" is not in the update dataset - tbl.update({ - "a": ["abc"], - "b": [456] - }) + tbl.update({"a": ["abc"], "b": [456]}) assert tbl.view().to_records() == [{"a": "abc", "b": 456, "c": 2}] def test_update_columnar_partial_unset(self): tbl = Table([{"a": "abc", "b": 1, "c": 2}, {"a": "def", "b": 3, "c": 4}], index="a") - tbl.update({ - "a": ["abc"], - "b": [None] - }) + tbl.update({"a": ["abc"], "b": [None]}) assert tbl.view().to_records() == [{"a": "abc", "b": None, "c": 2}, {"a": "def", "b": 3, "c": 4}] @@ -158,10 +124,7 @@ def test_update_partial_subcolumn(self): def test_update_partial_subcolumn_dict(self): tbl = Table([{"a": "abc", "b": 123, "c": 456}], index="a") - tbl.update({ - "a": ["abc"], - "c": [1234] - }) + tbl.update({"a": ["abc"], "c": [1234]}) assert tbl.view().to_records() == [{"a": "abc", "b": 123, "c": 1234}] def test_update_partial_cols_more_columns_than_table(self): @@ -181,20 +144,14 @@ def test_update_columnar_partial(self): # make sure already created views are notified properly def test_update_from_schema_notify(self): - tbl = Table({ - "a": str, - "b": int - }) + tbl = Table({"a": str, "b": int}) view = tbl.view() assert view.num_rows() == 0 tbl.update([{"a": "abc", "b": 123}]) assert view.to_records() == [{"a": "abc", "b": 123}] def test_update_columnar_from_schema_notify(self): - tbl = Table({ - "a": str, - "b": int - }) + tbl = Table({"a": str, "b": int}) view = tbl.view() assert view.num_rows() == 0 tbl.update({"a": ["abc"], "b": [123]}) @@ -239,116 +196,69 @@ def test_update_columnar_partial_notify(self): def test_update_bool_from_schema(self): bool_data = [{"a": True, "b": False}, {"a": True, "b": True}] - tbl = Table({ - "a": bool, - "b": bool - }) + tbl = Table({"a": bool, "b": bool}) tbl.update(bool_data) assert tbl.size() == 2 assert tbl.view().to_records() == bool_data def test_update_bool_str_from_schema(self): bool_data = [{"a": "True", "b": "False"}, {"a": "True", "b": "True"}] - tbl = Table({ - "a": bool, - "b": bool - }) + tbl = Table({"a": bool, "b": bool}) tbl.update(bool_data) assert tbl.size() == 2 - assert tbl.view().to_records() == [ - {"a": True, "b": False}, - {"a": True, "b": True}] + assert tbl.view().to_records() == [{"a": True, "b": False}, {"a": True, "b": True}] def test_update_bool_str_all_formats_from_schema(self): - bool_data = [ - {"a": "True", "b": "False"}, - {"a": "t", "b": "f"}, - {"a": "true", "b": "false"}, - {"a": 1, "b": 0}, - {"a": "on", "b": "off"} - ] - tbl = Table({ - "a": bool, - "b": bool - }) + bool_data = [{"a": "True", "b": "False"}, {"a": "t", "b": "f"}, {"a": "true", "b": "false"}, {"a": 1, "b": 0}, {"a": "on", "b": "off"}] + tbl = Table({"a": bool, "b": bool}) tbl.update(bool_data) assert tbl.size() == 5 - assert tbl.view().to_dict() == { - "a": [True, True, True, True, True], - "b": [False, False, False, False, False] - } + assert tbl.view().to_dict() == {"a": [True, True, True, True, True], "b": [False, False, False, False, False]} def test_update_bool_int_from_schema(self): bool_data = [{"a": 1, "b": 0}, {"a": 1, "b": 0}] - tbl = Table({ - "a": bool, - "b": bool - }) + tbl = Table({"a": bool, "b": bool}) tbl.update(bool_data) assert tbl.size() == 2 - assert tbl.view().to_dict() == { - "a": [True, True], - "b": [False, False] - } + assert tbl.view().to_dict() == {"a": [True, True], "b": [False, False]} # dates and datetimes def test_update_date(self): tbl = Table({"a": [date(2019, 7, 11)]}) tbl.update([{"a": date(2019, 7, 12)}]) - assert tbl.view().to_records() == [ - {"a": datetime(2019, 7, 11)}, - {"a": datetime(2019, 7, 12)} - ] + assert tbl.view().to_records() == [{"a": datetime(2019, 7, 11)}, {"a": datetime(2019, 7, 12)}] def test_update_date_np(self): tbl = Table({"a": [date(2019, 7, 11)]}) tbl.update([{"a": np.datetime64(date(2019, 7, 12))}]) - assert tbl.view().to_records() == [ - {"a": datetime(2019, 7, 11)}, - {"a": datetime(2019, 7, 12)} - ] + assert tbl.view().to_records() == [{"a": datetime(2019, 7, 11)}, {"a": datetime(2019, 7, 12)}] def test_update_datetime(self): tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]}) tbl.update([{"a": datetime(2019, 7, 12, 11, 0)}]) - assert tbl.view().to_records() == [ - {"a": datetime(2019, 7, 11, 11, 0)}, - {"a": datetime(2019, 7, 12, 11, 0)} - ] + assert tbl.view().to_records() == [{"a": datetime(2019, 7, 11, 11, 0)}, {"a": datetime(2019, 7, 12, 11, 0)}] def test_update_datetime_np(self): tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]}) tbl.update([{"a": np.datetime64(datetime(2019, 7, 12, 11, 0))}]) - assert tbl.view().to_records() == [ - {"a": datetime(2019, 7, 11, 11, 0)}, - {"a": datetime(2019, 7, 12, 11, 0)} - ] + assert tbl.view().to_records() == [{"a": datetime(2019, 7, 11, 11, 0)}, {"a": datetime(2019, 7, 12, 11, 0)}] def test_update_datetime_np_ts(self): tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]}) tbl.update([{"a": np.datetime64("2019-07-12T11:00")}]) - assert tbl.view().to_records() == [ - {"a": datetime(2019, 7, 11, 11, 0)}, - {"a": datetime(2019, 7, 12, 11, 0)} - ] + assert tbl.view().to_records() == [{"a": datetime(2019, 7, 11, 11, 0)}, {"a": datetime(2019, 7, 12, 11, 0)}] def test_update_datetime_timestamp_seconds(self, util): ts = util.to_timestamp(datetime(2019, 7, 12, 11, 0, 0)) tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]}) tbl.update([{"a": ts}]) - assert tbl.view().to_records() == [ - {"a": datetime(2019, 7, 11, 11, 0)}, - {"a": datetime(2019, 7, 12, 11, 0)} - ] + assert tbl.view().to_records() == [{"a": datetime(2019, 7, 11, 11, 0)}, {"a": datetime(2019, 7, 12, 11, 0)}] def test_update_datetime_timestamp_ms(self, util): ts = util.to_timestamp(datetime(2019, 7, 12, 11, 0, 0)) tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]}) tbl.update([{"a": ts}]) - assert tbl.view().to_records() == [ - {"a": datetime(2019, 7, 11, 11, 0)}, - {"a": datetime(2019, 7, 12, 11, 0)} - ] + assert tbl.view().to_records() == [{"a": datetime(2019, 7, 11, 11, 0)}, {"a": datetime(2019, 7, 12, 11, 0)}] # partial date & datetime updates @@ -381,17 +291,13 @@ def test_update_datetime_timestamp_seconds_partial(self, util): ts = util.to_timestamp(datetime(2019, 7, 12, 11, 0, 0)) tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)], "idx": [1]}, index="idx") tbl.update([{"a": ts, "idx": 1}]) - assert tbl.view().to_records() == [ - {"a": datetime(2019, 7, 12, 11, 0), "idx": 1} - ] + assert tbl.view().to_records() == [{"a": datetime(2019, 7, 12, 11, 0), "idx": 1}] def test_update_datetime_timestamp_ms_partial(self, util): ts = util.to_timestamp(datetime(2019, 7, 12, 11, 0, 0)) tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)], "idx": [1]}, index="idx") tbl.update([{"a": ts, "idx": 1}]) - assert tbl.view().to_records() == [ - {"a": datetime(2019, 7, 12, 11, 0), "idx": 1} - ] + assert tbl.view().to_records() == [{"a": datetime(2019, 7, 12, 11, 0), "idx": 1}] # updating dates using implicit index @@ -426,11 +332,7 @@ def test_update_implicit_index(self): data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}] tbl = Table(data) view = tbl.view() - tbl.update([{ - "__INDEX__": [0], - "a": 3, - "b": 15 - }]) + tbl.update([{"__INDEX__": [0], "a": 3, "b": 15}]) assert view.to_records() == [{"a": 3, "b": 15}, {"a": 2, "b": 3}] def test_update_implicit_index_dict_noop(self): @@ -439,36 +341,36 @@ def test_update_implicit_index_dict_noop(self): view = tbl.view() # "b" does not exist in dataset, so no-op - tbl.update({ - "__INDEX__": [0], - "a": [3], - }) + tbl.update( + { + "__INDEX__": [0], + "a": [3], + } + ) assert view.to_records() == [{"a": 3, "b": 2}, {"a": 2, "b": 3}] def test_update_implicit_index_dict_unset_with_null(self): data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}] tbl = Table(data) view = tbl.view() - + # unset because "b" is null - tbl.update({ - "__INDEX__": [0], - "a": [3], - "b": [None] - }) + tbl.update({"__INDEX__": [0], "a": [3], "b": [None]}) assert view.to_records() == [{"a": 3, "b": None}, {"a": 2, "b": 3}] def test_update_implicit_index_multi(self): data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}, {"a": 4, "b": 5}] tbl = Table(data) view = tbl.view() - tbl.update([{ - "__INDEX__": [0], - "a": 3, - }, { - "__INDEX__": [2], - "a": 5 - }]) + tbl.update( + [ + { + "__INDEX__": [0], + "a": 3, + }, + {"__INDEX__": [2], "a": 5}, + ] + ) assert view.to_records() == [{"a": 3, "b": 2}, {"a": 2, "b": 3}, {"a": 5, "b": 5}] def test_update_implicit_index_symmetric(self): @@ -477,77 +379,47 @@ def test_update_implicit_index_symmetric(self): view = tbl.view() records = view.to_records(index=True) idx = records[0]["__INDEX__"] - tbl.update([{ - "__INDEX__": idx, - "a": 3 - }]) + tbl.update([{"__INDEX__": idx, "a": 3}]) assert view.to_records() == [{"a": 3, "b": 2}, {"a": 2, "b": 3}] def test_update_explicit_index(self): data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}] tbl = Table(data, index="a") view = tbl.view() - tbl.update([{ - "a": 1, - "b": 3 - }]) + tbl.update([{"a": 1, "b": 3}]) assert view.to_records() == [{"a": 1, "b": 3}, {"a": 2, "b": 3}] def test_update_explicit_index_multi(self): data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}, {"a": 3, "b": 4}] tbl = Table(data, index="a") view = tbl.view() - tbl.update([{ - "a": 1, - "b": 3 - }, { - "a": 3, - "b": 5 - }]) + tbl.update([{"a": 1, "b": 3}, {"a": 3, "b": 5}]) assert view.to_records() == [{"a": 1, "b": 3}, {"a": 2, "b": 3}, {"a": 3, "b": 5}] def test_update_explicit_index_multi_append(self): data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}, {"a": 3, "b": 4}] tbl = Table(data, index="a") view = tbl.view() - tbl.update([{ - "a": 1, - "b": 3 - }, { - "a": 12, - "b": 5 - }]) + tbl.update([{"a": 1, "b": 3}, {"a": 12, "b": 5}]) assert view.to_records() == [{"a": 1, "b": 3}, {"a": 2, "b": 3}, {"a": 3, "b": 4}, {"a": 12, "b": 5}] def test_update_explicit_index_multi_append_noindex(self): data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}, {"a": 3, "b": 4}] tbl = Table(data, index="a") view = tbl.view() - tbl.update([{ - "a": 1, - "b": 3 - }, { - "b": 5 - }]) + tbl.update([{"a": 1, "b": 3}, {"b": 5}]) assert view.to_records() == [{"a": None, "b": 5}, {"a": 1, "b": 3}, {"a": 2, "b": 3}, {"a": 3, "b": 4}] def test_update_implicit_index_with_explicit_unset(self): data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}] tbl = Table(data, index="a") view = tbl.view() - tbl.update([{ - "__INDEX__": [1], - "b": 3 - }]) + tbl.update([{"__INDEX__": [1], "b": 3}]) assert view.to_records() == [{"a": 1, "b": 3}, {"a": 2, "b": 3}] def test_update_implicit_index_with_explicit_set(self): data = [{"a": 1, "b": 2}, {"a": 2, "b": 3}] tbl = Table(data, index="a") view = tbl.view() - tbl.update([{ - "__INDEX__": [1], - "a": 1, # should ignore re-specification of pkey - "b": 3 - }]) + tbl.update([{"__INDEX__": [1], "a": 1, "b": 3}]) # should ignore re-specification of pkey assert view.to_records() == [{"a": 1, "b": 3}, {"a": 2, "b": 3}] diff --git a/python/perspective/perspective/tests/table/test_update_arrow.py b/python/perspective/perspective/tests/table/test_update_arrow.py index 2fb2d60cb2..258d1370fc 100644 --- a/python/perspective/perspective/tests/table/test_update_arrow.py +++ b/python/perspective/perspective/tests/table/test_update_arrow.py @@ -30,383 +30,266 @@ class TestUpdateArrow(object): - # files def test_update_arrow_updates_stream_file(self): - tbl = Table({ - "a": int, - "b": float, - "c": str - }) + tbl = Table({"a": int, "b": float, "c": str}) - with open(SOURCE_STREAM_ARROW, mode='rb') as file: # b is important -> binary + with open(SOURCE_STREAM_ARROW, mode="rb") as file: # b is important -> binary tbl.update(file.read()) assert tbl.size() == 4 - assert tbl.schema() == { - "a": int, - "b": float, - "c": str - } + assert tbl.schema() == {"a": int, "b": float, "c": str} - with open(SOURCE_FILE_ARROW, mode='rb') as file: + with open(SOURCE_FILE_ARROW, mode="rb") as file: tbl.update(file.read()) assert tbl.size() == 8 - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4] * 2, - "b": [1.5, 2.5, 3.5, 4.5] * 2, - "c": ["a", "b", "c", "d"] * 2 - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4] * 2, "b": [1.5, 2.5, 3.5, 4.5] * 2, "c": ["a", "b", "c", "d"] * 2} def test_update_arrow_partial_updates_file(self): - tbl = Table({ - "a": int, - "b": float, - "c": str - }, index="a") + tbl = Table({"a": int, "b": float, "c": str}, index="a") - with open(SOURCE_STREAM_ARROW, mode='rb') as src: + with open(SOURCE_STREAM_ARROW, mode="rb") as src: tbl.update(src.read()) assert tbl.size() == 4 - with open(PARTIAL_ARROW, mode='rb') as partial: + with open(PARTIAL_ARROW, mode="rb") as partial: tbl.update(partial.read()) assert tbl.size() == 4 - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4], - "b": [100.5, 2.5, 3.5, 400.5], - "c": ["x", "b", "c", "y"] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4], "b": [100.5, 2.5, 3.5, 400.5], "c": ["x", "b", "c", "y"]} def test_update_arrow_updates_dict_file(self): - tbl = Table({ - "a": str, - "b": str - }) + tbl = Table({"a": str, "b": str}) - with open(DICT_ARROW, mode='rb') as src: + with open(DICT_ARROW, mode="rb") as src: tbl.update(src.read()) assert tbl.size() == 5 - with open(DICT_UPDATE_ARROW, mode='rb') as partial: + with open(DICT_UPDATE_ARROW, mode="rb") as partial: tbl.update(partial.read()) assert tbl.size() == 8 - assert tbl.view().to_dict() == { - "a": ["abc", "def", "def", None, "abc", None, "update1", "update2"], - "b": ["klm", "hij", None, "hij", "klm", "update3", None, "update4"] - } + assert tbl.view().to_dict() == {"a": ["abc", "def", "def", None, "abc", None, "update1", "update2"], "b": ["klm", "hij", None, "hij", "klm", "update3", None, "update4"]} @mark.skip def test_update_arrow_updates_dict_partial_file(self): tbl = None v = None - with open(DICT_ARROW, mode='rb') as src: + with open(DICT_ARROW, mode="rb") as src: tbl = Table(src.read(), index="a") v = tbl.view() assert v.num_rows() == 2 - assert v.to_dict() == { - "a": ["abc", "def"], - "b": ["klm", "hij"] - } + assert v.to_dict() == {"a": ["abc", "def"], "b": ["klm", "hij"]} - with open(DICT_UPDATE_ARROW, mode='rb') as partial: + with open(DICT_UPDATE_ARROW, mode="rb") as partial: tbl.update(partial.read()) v.num_rows() == 4 - assert v.to_dict() == { - "a": ["abc", "def", "update1", "update2"], - "b": ["klm", "hij", None, "update4"] - } + assert v.to_dict() == {"a": ["abc", "def", "update1", "update2"], "b": ["klm", "hij", None, "update4"]} # update with file arrow with more columns than in schema def test_update_arrow_updates_more_columns_stream_file(self): - tbl = Table({ - "a": int, - "b": float, - }) + tbl = Table( + { + "a": int, + "b": float, + } + ) - with open(SOURCE_STREAM_ARROW, mode='rb') as file: # b is important -> binary + with open(SOURCE_STREAM_ARROW, mode="rb") as file: # b is important -> binary tbl.update(file.read()) assert tbl.size() == 4 - assert tbl.schema() == { - "a": int, - "b": float - } + assert tbl.schema() == {"a": int, "b": float} - with open(SOURCE_FILE_ARROW, mode='rb') as file: + with open(SOURCE_FILE_ARROW, mode="rb") as file: tbl.update(file.read()) assert tbl.size() == 8 - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4] * 2, - "b": [1.5, 2.5, 3.5, 4.5] * 2 - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4] * 2, "b": [1.5, 2.5, 3.5, 4.5] * 2} def test_update_arrow_partial_updates_more_columns_file(self): - tbl = Table({ - "a": int, - "c": str - }, index="a") + tbl = Table({"a": int, "c": str}, index="a") - with open(SOURCE_STREAM_ARROW, mode='rb') as src: + with open(SOURCE_STREAM_ARROW, mode="rb") as src: tbl.update(src.read()) assert tbl.size() == 4 - with open(PARTIAL_ARROW, mode='rb') as partial: + with open(PARTIAL_ARROW, mode="rb") as partial: tbl.update(partial.read()) assert tbl.size() == 4 - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4], - "c": ["x", "b", "c", "y"] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4], "c": ["x", "b", "c", "y"]} def test_update_arrow_updates_dict_more_columns_file(self): - tbl = Table({ - "a": str, - }) + tbl = Table( + { + "a": str, + } + ) - with open(DICT_ARROW, mode='rb') as src: + with open(DICT_ARROW, mode="rb") as src: tbl.update(src.read()) assert tbl.size() == 5 - with open(DICT_UPDATE_ARROW, mode='rb') as partial: + with open(DICT_UPDATE_ARROW, mode="rb") as partial: tbl.update(partial.read()) assert tbl.size() == 8 - assert tbl.view().to_dict() == { - "a": ["abc", "def", "def", None, "abc", None, "update1", "update2"] - } + assert tbl.view().to_dict() == {"a": ["abc", "def", "def", None, "abc", None, "update1", "update2"]} @mark.skip def test_update_arrow_updates_dict_more_columns_partial_file(self): - tbl = Table({ - "a": str - }, index="a") + tbl = Table({"a": str}, index="a") - with open(DICT_ARROW, mode='rb') as src: + with open(DICT_ARROW, mode="rb") as src: tbl.update(src.read()) assert tbl.size() == 4 - with open(DICT_UPDATE_ARROW, mode='rb') as partial: + with open(DICT_UPDATE_ARROW, mode="rb") as partial: tbl.update(partial.read()) assert tbl.size() == 4 - assert tbl.view().to_dict() == { - "a": ["abc", "def", "update1", "update2"] - } + assert tbl.view().to_dict() == {"a": ["abc", "def", "update1", "update2"]} # update with file arrow with less columns than in schema def test_update_arrow_updates_less_columns_stream_file(self): - tbl = Table({ - "a": int, - "x": float, - }) + tbl = Table( + { + "a": int, + "x": float, + } + ) - with open(SOURCE_STREAM_ARROW, mode='rb') as file: # b is important -> binary + with open(SOURCE_STREAM_ARROW, mode="rb") as file: # b is important -> binary tbl.update(file.read()) assert tbl.size() == 4 - assert tbl.schema() == { - "a": int, - "x": float - } + assert tbl.schema() == {"a": int, "x": float} - with open(SOURCE_FILE_ARROW, mode='rb') as file: + with open(SOURCE_FILE_ARROW, mode="rb") as file: tbl.update(file.read()) assert tbl.size() == 8 - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4] * 2, - "x": [None for i in range(8)] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4] * 2, "x": [None for i in range(8)]} def test_update_arrow_partial_updates_less_columns_file(self): - tbl = Table({ - "a": int, - "x": str - }, index="a") + tbl = Table({"a": int, "x": str}, index="a") - with open(SOURCE_STREAM_ARROW, mode='rb') as src: + with open(SOURCE_STREAM_ARROW, mode="rb") as src: tbl.update(src.read()) assert tbl.size() == 4 - with open(PARTIAL_ARROW, mode='rb') as partial: + with open(PARTIAL_ARROW, mode="rb") as partial: tbl.update(partial.read()) assert tbl.size() == 4 - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4], - "x": [None for i in range(4)] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4], "x": [None for i in range(4)]} def test_update_arrow_updates_dict_less_columns_file(self): - tbl = Table({ - "a": str, - "x": str - }) + tbl = Table({"a": str, "x": str}) - with open(DICT_ARROW, mode='rb') as src: + with open(DICT_ARROW, mode="rb") as src: tbl.update(src.read()) assert tbl.size() == 5 - with open(DICT_UPDATE_ARROW, mode='rb') as partial: + with open(DICT_UPDATE_ARROW, mode="rb") as partial: tbl.update(partial.read()) assert tbl.size() == 8 - assert tbl.view().to_dict() == { - "a": ["abc", "def", "def", None, "abc", None, "update1", "update2"], - "x": [None for i in range(8)] - } + assert tbl.view().to_dict() == {"a": ["abc", "def", "def", None, "abc", None, "update1", "update2"], "x": [None for i in range(8)]} @mark.skip def test_update_arrow_updates_dict_less_columns_partial_file(self): - tbl = Table({ - "a": str, - "x": str - }, index="a") + tbl = Table({"a": str, "x": str}, index="a") - with open(DICT_ARROW, mode='rb') as src: + with open(DICT_ARROW, mode="rb") as src: tbl.update(src.read()) assert tbl.size() == 4 - with open(DICT_UPDATE_ARROW, mode='rb') as partial: + with open(DICT_UPDATE_ARROW, mode="rb") as partial: tbl.update(partial.read()) assert tbl.size() == 4 - assert tbl.view().to_dict() == { - "a": ["abc", "def", "update1", "update2"], - "x": [None for i in range(4)] - } + assert tbl.view().to_dict() == {"a": ["abc", "def", "update1", "update2"], "x": [None for i in range(4)]} # update int schema with int def test_update_arrow_update_int_schema_with_uint8(self, util): array = [random.randint(0, 127) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.uint8) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.uint8)}) - schema = pa.schema({ - "a": pa.uint8() - }) + schema = pa.schema({"a": pa.uint8()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_int_schema_with_uint16(self, util): array = [random.randint(0, 32767) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.uint16) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.uint16)}) - schema = pa.schema({ - "a": pa.uint16() - }) + schema = pa.schema({"a": pa.uint16()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_int_schema_with_uint32(self, util): array = [random.randint(0, 2000000) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.uint32) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.uint32)}) - schema = pa.schema({ - "a": pa.uint32() - }) + schema = pa.schema({"a": pa.uint32()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_int_schema_with_uint64(self, util): array = [random.randint(0, 20000000) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.uint64) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.uint64)}) - schema = pa.schema({ - "a": pa.uint64() - }) + schema = pa.schema({"a": pa.uint64()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_int_schema_with_int8(self, util): array = [random.randint(-127, 127) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.int8) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.int8)}) - schema = pa.schema({ - "a": pa.int8() - }) + schema = pa.schema({"a": pa.int8()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_int_schema_with_int16(self, util): array = [random.randint(-32767, 32767) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.int16) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.int16)}) - schema = pa.schema({ - "a": pa.int16() - }) + schema = pa.schema({"a": pa.int16()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_int_schema_with_int32(self, util): array = [random.randint(-2000000, 2000000) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.int32) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.int32)}) - schema = pa.schema({ - "a": pa.int32() - }) + schema = pa.schema({"a": pa.int32()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_int_schema_with_int64(self, util): array = [random.randint(-20000000, 20000000) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.int64) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.int64)}) - schema = pa.schema({ - "a": pa.int64() - }) + schema = pa.schema({"a": pa.int64()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == [x * 1.0 for x in array] @@ -414,172 +297,112 @@ def test_update_arrow_update_int_schema_with_int64(self, util): def test_update_arrow_update_float_schema_with_uint8(self, util): array = [random.randint(0, 127) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.uint8) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.uint8)}) - schema = pa.schema({ - "a": pa.uint8() - }) + schema = pa.schema({"a": pa.uint8()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": float - }) + tbl = Table({"a": float}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_float_schema_with_uint16(self, util): array = [random.randint(0, 32767) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.uint16) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.uint16)}) - schema = pa.schema({ - "a": pa.uint16() - }) + schema = pa.schema({"a": pa.uint16()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": float - }) + tbl = Table({"a": float}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_float_schema_with_uint32(self, util): array = [random.randint(0, 2000000) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.uint32) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.uint32)}) - schema = pa.schema({ - "a": pa.uint32() - }) + schema = pa.schema({"a": pa.uint32()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": float - }) + tbl = Table({"a": float}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_float_schema_with_uint64(self, util): array = [random.randint(0, 20000000) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.uint64) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.uint64)}) - schema = pa.schema({ - "a": pa.uint64() - }) + schema = pa.schema({"a": pa.uint64()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": float - }) + tbl = Table({"a": float}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_float_schema_with_int8(self, util): array = [random.randint(-127, 127) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.int8) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.int8)}) - schema = pa.schema({ - "a": pa.int8() - }) + schema = pa.schema({"a": pa.int8()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": float - }) + tbl = Table({"a": float}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_float_schema_with_int16(self, util): array = [random.randint(-32767, 32767) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.int16) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.int16)}) - schema = pa.schema({ - "a": pa.int16() - }) + schema = pa.schema({"a": pa.int16()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": float - }) + tbl = Table({"a": float}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_float_schema_with_int32(self, util): array = [random.randint(-2000000, 2000000) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.int32) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.int32)}) - schema = pa.schema({ - "a": pa.int32() - }) + schema = pa.schema({"a": pa.int32()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": float - }) + tbl = Table({"a": float}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_float_schema_with_int64(self, util): array = [random.randint(-20000000, 20000000) for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.int64) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.int64)}) - schema = pa.schema({ - "a": pa.int64() - }) + schema = pa.schema({"a": pa.int64()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": float - }) + tbl = Table({"a": float}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array # updating int schema with float def test_update_arrow_update_int_schema_with_float32(self, util): array = [random.randint(-2000000, 2000000) * 0.5 for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.float32) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.float32)}) - schema = pa.schema({ - "a": pa.float32() - }) + schema = pa.schema({"a": pa.float32()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == [int(x) for x in array] def test_update_arrow_update_int_schema_with_float64(self, util): array = [random.randint(-20000000, 20000000) * random.random() for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.float64) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.float64)}) - schema = pa.schema({ - "a": pa.float64() - }) + schema = pa.schema({"a": pa.float64()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == [int(x) for x in array] @@ -587,35 +410,23 @@ def test_update_arrow_update_int_schema_with_float64(self, util): def test_update_arrow_update_float_schema_with_float32(self, util): array = [random.randint(-2000000, 2000000) * 0.5 for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.float32) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.float32)}) - schema = pa.schema({ - "a": pa.float32() - }) + schema = pa.schema({"a": pa.float32()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": float - }) + tbl = Table({"a": float}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array def test_update_arrow_update_float_schema_with_float64(self, util): array = [random.randint(-20000000, 20000000) * random.random() for i in range(100)] - data = pd.DataFrame({ - "a": np.array(array, dtype=np.float64) - }) + data = pd.DataFrame({"a": np.array(array, dtype=np.float64)}) - schema = pa.schema({ - "a": pa.float64() - }) + schema = pa.schema({"a": pa.float64()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": float - }) + tbl = Table({"a": float}) tbl.update(arrow) assert tbl.view().to_dict()["a"] == array @@ -623,19 +434,13 @@ def test_update_arrow_update_float_schema_with_float64(self, util): def test_update_arrow_update_date_schema_with_date32(self, util): array = [date(2019, 2, i) for i in range(1, 11)] - data = pd.DataFrame({ - "a": array - }) + data = pd.DataFrame({"a": array}) - schema = pa.schema({ - "a": pa.date32() - }) + schema = pa.schema({"a": pa.date32()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": date - }) + tbl = Table({"a": date}) tbl.update(arrow) @@ -643,19 +448,13 @@ def test_update_arrow_update_date_schema_with_date32(self, util): def test_update_arrow_update_date_schema_with_date64(self, util): array = [date(2019, 2, i) for i in range(1, 11)] - data = pd.DataFrame({ - "a": array - }) + data = pd.DataFrame({"a": array}) - schema = pa.schema({ - "a": pa.date64() - }) + schema = pa.schema({"a": pa.date64()}) arrow = util.make_arrow_from_pandas(data, schema) - tbl = Table({ - "a": date - }) + tbl = Table({"a": date}) tbl.update(arrow) @@ -666,293 +465,182 @@ def test_update_arrow_update_datetime_schema_with_timestamp(self, util): [datetime(2019, 2, i, 9) for i in range(1, 11)], [datetime(2019, 2, i, 10) for i in range(1, 11)], [datetime(2019, 2, i, 11) for i in range(1, 11)], - [datetime(2019, 2, i, 12) for i in range(1, 11)] + [datetime(2019, 2, i, 12) for i in range(1, 11)], ] arrow_data = util.make_arrow( - names, data, types=[ + names, + data, + types=[ pa.timestamp("s"), pa.timestamp("ms"), pa.timestamp("us"), pa.timestamp("ns"), - ] + ], ) - tbl = Table({ - "a": datetime, - "b": datetime, - "c": datetime, - "d": datetime, - }) + tbl = Table( + { + "a": datetime, + "b": datetime, + "c": datetime, + "d": datetime, + } + ) tbl.update(arrow_data) assert tbl.size() == 10 - assert tbl.view().to_dict() == { - "a": data[0], - "b": data[1], - "c": data[2], - "d": data[3] - } + assert tbl.view().to_dict() == {"a": data[0], "b": data[1], "c": data[2], "d": data[3]} # streams def test_update_arrow_updates_int_stream(self, util): data = [list(range(10)) for i in range(4)] arrow_data = util.make_arrow(names, data) - tbl = Table({ - "a": int, - "b": int, - "c": int, - "d": int - }) + tbl = Table({"a": int, "b": int, "c": int, "d": int}) tbl.update(arrow_data) assert tbl.size() == 10 - assert tbl.view().to_dict() == { - "a": data[0], - "b": data[1], - "c": data[2], - "d": data[3] - } + assert tbl.view().to_dict() == {"a": data[0], "b": data[1], "c": data[2], "d": data[3]} def test_update_arrow_updates_float_stream(self, util): - data = [ - [i for i in range(10)], - [i * 1.5 for i in range(10)] - ] + data = [[i for i in range(10)], [i * 1.5 for i in range(10)]] arrow_data = util.make_arrow(["a", "b"], data) - tbl = Table({ - "a": int, - "b": float, - }) + tbl = Table( + { + "a": int, + "b": float, + } + ) tbl.update(arrow_data) assert tbl.size() == 10 - assert tbl.view().to_dict() == { - "a": data[0], - "b": data[1] - } + assert tbl.view().to_dict() == {"a": data[0], "b": data[1]} def test_update_arrow_updates_decimal128_stream(self, util): - data = [ - [i * 1000000000 for i in range(10)] - ] + data = [[i * 1000000000 for i in range(10)]] arrow_data = util.make_arrow(["a"], data, types=[pa.decimal128(10)]) - tbl = Table({ - "a": int - }) + tbl = Table({"a": int}) tbl.update(arrow_data) assert tbl.size() == 10 - assert tbl.view().to_dict() == { - "a": data[0] - } + assert tbl.view().to_dict() == {"a": data[0]} def test_update_arrow_updates_bool_stream(self, util): - data = [ - [True if i % 2 == 0 else False for i in range(10)] - ] + data = [[True if i % 2 == 0 else False for i in range(10)]] arrow_data = util.make_arrow(["a"], data) - tbl = Table({ - "a": bool - }) + tbl = Table({"a": bool}) tbl.update(arrow_data) assert tbl.size() == 10 - assert tbl.view().to_dict() == { - "a": data[0] - } + assert tbl.view().to_dict() == {"a": data[0]} def test_update_arrow_updates_date32_stream(self, util): - data = [ - [date(2019, 2, i) for i in range(1, 11)] - ] + data = [[date(2019, 2, i) for i in range(1, 11)]] arrow_data = util.make_arrow(["a"], data, types=[pa.date32()]) - tbl = Table({ - "a": date - }) + tbl = Table({"a": date}) tbl.update(arrow_data) assert tbl.size() == 10 - assert tbl.view().to_dict() == { - "a": [datetime(2019, 2, i) for i in range(1, 11)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 2, i) for i in range(1, 11)]} def test_update_arrow_updates_date64_stream(self, util): - data = [ - [date(2019, 2, i) for i in range(1, 11)] - ] + data = [[date(2019, 2, i) for i in range(1, 11)]] arrow_data = util.make_arrow(["a"], data, types=[pa.date64()]) - tbl = Table({ - "a": date - }) + tbl = Table({"a": date}) tbl.update(arrow_data) assert tbl.size() == 10 - assert tbl.view().to_dict() == { - "a": [datetime(2019, 2, i) for i in range(1, 11)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 2, i) for i in range(1, 11)]} def test_update_arrow_updates_timestamp_all_formats_stream(self, util): data = [ [datetime(2019, 2, i, 9) for i in range(1, 11)], [datetime(2019, 2, i, 10) for i in range(1, 11)], [datetime(2019, 2, i, 11) for i in range(1, 11)], - [datetime(2019, 2, i, 12) for i in range(1, 11)] + [datetime(2019, 2, i, 12) for i in range(1, 11)], ] arrow_data = util.make_arrow( - names, data, types=[ + names, + data, + types=[ pa.timestamp("s"), pa.timestamp("ms"), pa.timestamp("us"), pa.timestamp("ns"), - ] + ], ) - tbl = Table({ - "a": datetime, - "b": datetime, - "c": datetime, - "d": datetime - }) + tbl = Table({"a": datetime, "b": datetime, "c": datetime, "d": datetime}) tbl.update(arrow_data) assert tbl.size() == 10 - assert tbl.view().to_dict() == { - "a": data[0], - "b": data[1], - "c": data[2], - "d": data[3] - } + assert tbl.view().to_dict() == {"a": data[0], "b": data[1], "c": data[2], "d": data[3]} def test_update_arrow_updates_string_stream(self, util): - data = [ - [str(i) for i in range(10)] - ] + data = [[str(i) for i in range(10)]] arrow_data = util.make_arrow(["a"], data, types=[pa.string()]) - tbl = Table({ - "a": str - }) + tbl = Table({"a": str}) tbl.update(arrow_data) assert tbl.size() == 10 - assert tbl.view().to_dict() == { - "a": data[0] - } + assert tbl.view().to_dict() == {"a": data[0]} def test_update_arrow_updates_dictionary_stream(self, util): - data = [ - ([0, 1, 1, None], ["a", "b"]), - ([0, 1, None, 2], ["x", "y", "z"]) - ] + data = [([0, 1, 1, None], ["a", "b"]), ([0, 1, None, 2], ["x", "y", "z"])] arrow_data = util.make_dictionary_arrow(["a", "b"], data) - tbl = Table({ - "a": str, - "b": str - }) + tbl = Table({"a": str, "b": str}) tbl.update(arrow_data) assert tbl.size() == 4 - assert tbl.view().to_dict() == { - "a": ["a", "b", "b", None], - "b": ["x", "y", None, "z"] - } + assert tbl.view().to_dict() == {"a": ["a", "b", "b", None], "b": ["x", "y", None, "z"]} def test_update_arrow_partial_updates_dictionary_stream(self, util): - data = [ - ([0, 1, 1, None], ["a", "b"]), - ([0, 1, None, 2], ["x", "y", "z"]) - ] + data = [([0, 1, 1, None], ["a", "b"]), ([0, 1, None, 2], ["x", "y", "z"])] arrow_data = util.make_dictionary_arrow(["a", "b"], data) - tbl = Table({ - "a": str, - "b": str - }, index="a") + tbl = Table({"a": str, "b": str}, index="a") tbl.update(arrow_data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [None, "a", "b"], - "b": ["z", "x", "y"] - } + assert tbl.view().to_dict() == {"a": [None, "a", "b"], "b": ["z", "x", "y"]} @mark.skip def test_update_arrow_partial_updates_dictionary_stream_duplicates(self, util): """If there are duplicate values in the dictionary, primary keys may be duplicated if the column is used as an index. Skip this test for now - still looking for the best way to fix.""" - data = [ - ([0, 1, 1, None, 2], ["a", "b", "a"]), - ([0, 1, None, 2, 1], ["x", "y", "z"]) - ] + data = [([0, 1, 1, None, 2], ["a", "b", "a"]), ([0, 1, None, 2, 1], ["x", "y", "z"])] arrow_data = util.make_dictionary_arrow(["a", "b"], data) - tbl = Table({ - "a": str, - "b": str - }, index="a") + tbl = Table({"a": str, "b": str}, index="a") tbl.update(arrow_data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [None, "a", "b"], - "b": ["z", "x", "y"] - } + assert tbl.view().to_dict() == {"a": [None, "a", "b"], "b": ["z", "x", "y"]} def test_update_arrow_partial_updates_more_columns_dictionary_stream(self, util): - data = [ - ([0, 1, 1, None], ["a", "b"]), - ([0, 1, None, 2], ["x", "y", "z"]) - ] + data = [([0, 1, 1, None], ["a", "b"]), ([0, 1, None, 2], ["x", "y", "z"])] arrow_data = util.make_dictionary_arrow(["a", "b"], data) - tbl = Table({ - "a": str - }, index="a") + tbl = Table({"a": str}, index="a") tbl.update(arrow_data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [None, "a", "b"] - } + assert tbl.view().to_dict() == {"a": [None, "a", "b"]} def test_update_arrow_partial_updates_less_columns_dictionary_stream(self, util): - data = [ - ([0, 1, 1, None], ["a", "b"]), - ([0, 1, None, 2], ["x", "y", "z"]) - ] + data = [([0, 1, 1, None], ["a", "b"]), ([0, 1, None, 2], ["x", "y", "z"])] arrow_data = util.make_dictionary_arrow(["a", "b"], data) - tbl = Table({ - "a": str, - "b": str, - "x": str - }, index="a") + tbl = Table({"a": str, "b": str, "x": str}, index="a") tbl.update(arrow_data) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - "a": [None, "a", "b"], - "b": ["z", "x", "y"], - "x": [None, None, None] - } + assert tbl.view().to_dict() == {"a": [None, "a", "b"], "b": ["z", "x", "y"], "x": [None, None, None]} def test_update_arrow_arbitary_order(self, util): - data = [[1, 2, 3, 4], - ["a", "b", "c", "d"], - [1, 2, 3, 4], - ["a", "b", "c", "d"]] + data = [[1, 2, 3, 4], ["a", "b", "c", "d"], [1, 2, 3, 4], ["a", "b", "c", "d"]] update_data = [[5, 6], ["e", "f"], [5, 6], ["e", "f"]] arrow = util.make_arrow(["a", "b", "c", "d"], data) update_arrow = util.make_arrow(["c", "b", "a", "d"], update_data) tbl = Table(arrow) - assert tbl.schema() == { - "a": int, - "b": str, - "c": int, - "d": str - } + assert tbl.schema() == {"a": int, "b": str, "c": int, "d": str} tbl.update(update_arrow) assert tbl.size() == 6 - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4, 5, 6], - "b": ["a", "b", "c", "d", "e", "f"], - "c": [1, 2, 3, 4, 5, 6], - "d": ["a", "b", "c", "d", "e", "f"] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4, 5, 6], "b": ["a", "b", "c", "d", "e", "f"], "c": [1, 2, 3, 4, 5, 6], "d": ["a", "b", "c", "d", "e", "f"]} # append @@ -962,91 +650,66 @@ def test_update_arrow_updates_append_int_stream(self, util): tbl = Table(arrow_data) tbl.update(arrow_data) assert tbl.size() == 20 - assert tbl.view().to_dict() == { - "a": data[0] + data[0], - "b": data[1] + data[1], - "c": data[2] + data[2], - "d": data[3] + data[3] - } + assert tbl.view().to_dict() == {"a": data[0] + data[0], "b": data[1] + data[1], "c": data[2] + data[2], "d": data[3] + data[3]} def test_update_arrow_updates_append_float_stream(self, util): - data = [ - [i for i in range(10)], - [i * 1.5 for i in range(10)] - ] + data = [[i for i in range(10)], [i * 1.5 for i in range(10)]] arrow_data = util.make_arrow(["a", "b"], data) tbl = Table(arrow_data) tbl.update(arrow_data) assert tbl.size() == 20 - assert tbl.view().to_dict() == { - "a": data[0] + data[0], - "b": data[1] + data[1] - } + assert tbl.view().to_dict() == {"a": data[0] + data[0], "b": data[1] + data[1]} def test_update_arrow_updates_append_decimal_stream(self, util): - data = [ - [i * 1000 for i in range(10)] - ] + data = [[i * 1000 for i in range(10)]] arrow_data = util.make_arrow(["a"], data, types=[pa.decimal128(4)]) tbl = Table(arrow_data) tbl.update(arrow_data) assert tbl.size() == 20 - assert tbl.view().to_dict() == { - "a": data[0] + data[0] - } + assert tbl.view().to_dict() == {"a": data[0] + data[0]} def test_update_arrow_updates_append_bool_stream(self, util): - data = [ - [True if i % 2 == 0 else False for i in range(10)] - ] + data = [[True if i % 2 == 0 else False for i in range(10)]] arrow_data = util.make_arrow(["a"], data) tbl = Table(arrow_data) tbl.update(arrow_data) assert tbl.size() == 20 - assert tbl.view().to_dict() == { - "a": data[0] + data[0] - } + assert tbl.view().to_dict() == {"a": data[0] + data[0]} def test_update_arrow_updates_append_date32_stream(self, util): - data = [ - [date(2019, 2, i) for i in range(1, 11)] - ] + data = [[date(2019, 2, i) for i in range(1, 11)]] out_data = [datetime(2019, 2, i) for i in range(1, 11)] arrow_data = util.make_arrow(["a"], data, types=[pa.date32()]) tbl = Table(arrow_data) tbl.update(arrow_data) assert tbl.size() == 20 - assert tbl.view().to_dict() == { - "a": out_data + out_data - } + assert tbl.view().to_dict() == {"a": out_data + out_data} def test_update_arrow_updates_append_date64_stream(self, util): - data = [ - [date(2019, 2, i) for i in range(1, 11)] - ] + data = [[date(2019, 2, i) for i in range(1, 11)]] out_data = [datetime(2019, 2, i) for i in range(1, 11)] arrow_data = util.make_arrow(["a"], data, types=[pa.date64()]) tbl = Table(arrow_data) tbl.update(arrow_data) assert tbl.size() == 20 - assert tbl.view().to_dict() == { - "a": out_data + out_data - } + assert tbl.view().to_dict() == {"a": out_data + out_data} def test_update_arrow_updates_append_timestamp_all_formats_stream(self, util): data = [ [datetime(2019, 2, i, 9) for i in range(1, 11)], [datetime(2019, 2, i, 10) for i in range(1, 11)], [datetime(2019, 2, i, 11) for i in range(1, 11)], - [datetime(2019, 2, i, 12) for i in range(1, 11)] + [datetime(2019, 2, i, 12) for i in range(1, 11)], ] arrow_data = util.make_arrow( - names, data, types=[ + names, + data, + types=[ pa.timestamp("s"), pa.timestamp("ms"), pa.timestamp("us"), pa.timestamp("ns"), - ] + ], ) tbl = Table(arrow_data) tbl.update(arrow_data) @@ -1059,46 +722,30 @@ def test_update_arrow_updates_append_timestamp_all_formats_stream(self, util): } def test_update_arrow_updates_append_string_stream(self, util): - data = [ - [str(i) for i in range(10)] - ] + data = [[str(i) for i in range(10)]] arrow_data = util.make_arrow(["a"], data, types=[pa.string()]) tbl = Table(arrow_data) tbl.update(arrow_data) assert tbl.size() == 20 - assert tbl.view().to_dict() == { - "a": data[0] + data[0] - } + assert tbl.view().to_dict() == {"a": data[0] + data[0]} def test_update_arrow_updates_append_dictionary_stream(self, util): - data = [ - ([0, 1, 1, None], ["a", "b"]), - ([0, 1, None, 2], ["x", "y", "z"]) - ] + data = [([0, 1, 1, None], ["a", "b"]), ([0, 1, None, 2], ["x", "y", "z"])] arrow_data = util.make_dictionary_arrow(["a", "b"], data) tbl = Table(arrow_data) tbl.update(arrow_data) assert tbl.size() == 8 - assert tbl.view().to_dict() == { - "a": ["a", "b", "b", None, "a", "b", "b", None], - "b": ["x", "y", None, "z", "x", "y", None, "z"] - } + assert tbl.view().to_dict() == {"a": ["a", "b", "b", None, "a", "b", "b", None], "b": ["x", "y", None, "z", "x", "y", None, "z"]} def test_update_arrow_updates_append_dictionary_stream_legacy(self, util): - data = [ - ([0, 1, 1, None], ["a", "b"]), - ([0, 1, None, 2], ["x", "y", "z"]) - ] + data = [([0, 1, 1, None], ["a", "b"]), ([0, 1, None, 2], ["x", "y", "z"])] arrow_data = util.make_dictionary_arrow(["a", "b"], data, legacy=True) tbl = Table(arrow_data) tbl.update(arrow_data) assert tbl.size() == 8 - assert tbl.view().to_dict() == { - "a": ["a", "b", "b", None, "a", "b", "b", None], - "b": ["x", "y", None, "z", "x", "y", None, "z"] - } + assert tbl.view().to_dict() == {"a": ["a", "b", "b", None, "a", "b", "b", None], "b": ["x", "y", None, "z", "x", "y", None, "z"]} # indexed @@ -1108,16 +755,10 @@ def test_update_arrow_partial_indexed(self, util): arrow = util.make_arrow(["a", "b"], data) update_arrow = util.make_arrow(["a", "b"], update_data) tbl = Table(arrow, index="a") - assert tbl.schema() == { - "a": int, - "b": str - } + assert tbl.schema() == {"a": int, "b": str} tbl.update(update_arrow) assert tbl.size() == 4 - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4], - "b": ["a", "x", "c", "y"] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4], "b": ["a", "x", "c", "y"]} # update specific columns @@ -1127,16 +768,10 @@ def test_update_arrow_specific_column(self, util): arrow = util.make_arrow(["a", "b"], data) update_arrow = util.make_arrow(["a"], update_data) tbl = Table(arrow) - assert tbl.schema() == { - "a": int, - "b": str - } + assert tbl.schema() == {"a": int, "b": str} tbl.update(update_arrow) assert tbl.size() == 7 - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4, 2, 3, 4], - "b": ["a", "b", "c", "d", None, None, None] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4, 2, 3, 4], "b": ["a", "b", "c", "d", None, None, None]} # try to fuzz column order @@ -1149,9 +784,7 @@ def test_update_arrow_column_order_str(self, util): tbl = Table({name: str for name in names}) tbl.update(arrow) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - name: data[0] for name in names - } + assert tbl.view().to_dict() == {name: data[0] for name in names} def test_update_arrow_column_order_int(self, util): data = [[1, 2, 3] for i in range(10)] @@ -1161,9 +794,7 @@ def test_update_arrow_column_order_int(self, util): tbl = Table({name: int for name in names}) tbl.update(arrow) assert tbl.size() == 3 - assert tbl.view().to_dict() == { - name: data[0] for name in names - } + assert tbl.view().to_dict() == {name: data[0] for name in names} def test_update_arrow_thread_safe_int_index(self, util): data = [["a", "b", "c"] for i in range(10)] diff --git a/python/perspective/perspective/tests/table/test_update_numpy.py b/python/perspective/perspective/tests/table/test_update_numpy.py index 4f45bd6d86..df45158cd8 100644 --- a/python/perspective/perspective/tests/table/test_update_numpy.py +++ b/python/perspective/perspective/tests/table/test_update_numpy.py @@ -17,299 +17,152 @@ class TestUpdateNumpy(object): - def test_update_np(self): tbl = Table({"a": [1, 2, 3, 4]}) tbl.update({"a": np.array([5, 6, 7, 8])}) - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4, 5, 6, 7, 8] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4, 5, 6, 7, 8]} def test_update_np_one_col(self): - tbl = Table({ - "a": np.array([1, 2, 3, 4]), - "b": np.array([2, 3, 4, 5]) - }) + tbl = Table({"a": np.array([1, 2, 3, 4]), "b": np.array([2, 3, 4, 5])}) tbl.update({"a": np.array([5, 6, 7, 8])}) - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4, 5, 6, 7, 8], - "b": [2, 3, 4, 5, None, None, None, None] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4, 5, 6, 7, 8], "b": [2, 3, 4, 5, None, None, None, None]} def test_update_np_bool_str(self): - tbl = Table({ - "a": [True] - }) + tbl = Table({"a": [True]}) - assert tbl.schema() == { - "a": bool - } + assert tbl.schema() == {"a": bool} - tbl.update({ - "a": np.array(["False"]) - }) + tbl.update({"a": np.array(["False"])}) - assert tbl.view().to_dict() == { - "a": [True, False] - } + assert tbl.view().to_dict() == {"a": [True, False]} def test_update_np_date(self): - tbl = Table({ - "a": [date(2019, 7, 11)] - }) + tbl = Table({"a": [date(2019, 7, 11)]}) - assert tbl.schema() == { - "a": date - } + assert tbl.schema() == {"a": date} - tbl.update({ - "a": np.array([date(2019, 7, 12)]) - }) + tbl.update({"a": np.array([date(2019, 7, 12)])}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11), datetime(2019, 7, 12)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11), datetime(2019, 7, 12)]} def test_update_np_date_timestamp(self, util): - tbl = Table({ - "a": [date(2019, 7, 11)] - }) + tbl = Table({"a": [date(2019, 7, 11)]}) - assert tbl.schema() == { - "a": date - } + assert tbl.schema() == {"a": date} ts = util.to_timestamp(datetime(2019, 7, 12)) - tbl.update({ - "a": np.array([ts]) - }) + tbl.update({"a": np.array([ts])}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11), datetime(2019, 7, 12)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11), datetime(2019, 7, 12)]} def test_update_np_datetime(self): - tbl = Table({ - "a": [np.datetime64(datetime(2019, 7, 11, 11, 0))] - }) + tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))]}) - tbl.update({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype=datetime) - }) + tbl.update({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype=datetime)}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)]} def test_update_np_datetime_str(self): - tbl = Table({ - "a": [np.datetime64(datetime(2019, 7, 11, 11, 0))] - }) + tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))]}) - tbl.update({ - "a": np.array(["2019/7/12 11:00:00"]) - }) + tbl.update({"a": np.array(["2019/7/12 11:00:00"])}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)]} def test_update_np_datetime_timestamp_s(self, util): - tbl = Table({ - "a": [np.datetime64(datetime(2019, 7, 11, 11, 0))] - }) + tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))]}) - tbl.update({ - "a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0))]) - }) + tbl.update({"a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0))])}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)]} def test_update_np_datetime_timestamp_ms(self, util): - tbl = Table({ - "a": [np.datetime64(datetime(2019, 7, 11, 11, 0))] - }) + tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))]}) - tbl.update({ - "a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0)) * 1000]) - }) + tbl.update({"a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0)) * 1000])}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)]} def test_update_np_partial(self): - tbl = Table({ - "a": [1, 2, 3, 4], - "b": ["a", "b", "c", "d"] - }, index="b") + tbl = Table({"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"]}, index="b") - tbl.update({ - "a": np.array([5, 6, 7, 8]), - "b": np.array(["a", "b", "c", "d"], dtype=object) - }) + tbl.update({"a": np.array([5, 6, 7, 8]), "b": np.array(["a", "b", "c", "d"], dtype=object)}) - assert tbl.view().to_dict() == { - "a": [5, 6, 7, 8], - "b": ["a", "b", "c", "d"] - } + assert tbl.view().to_dict() == {"a": [5, 6, 7, 8], "b": ["a", "b", "c", "d"]} def test_update_np_partial_implicit(self): tbl = Table({"a": [1, 2, 3, 4]}) - tbl.update({ - "a": np.array([5, 6, 7, 8]), - "__INDEX__": np.array([0, 1, 2, 3]) - }) + tbl.update({"a": np.array([5, 6, 7, 8]), "__INDEX__": np.array([0, 1, 2, 3])}) - assert tbl.view().to_dict() == { - "a": [5, 6, 7, 8] - } + assert tbl.view().to_dict() == {"a": [5, 6, 7, 8]} def test_update_np_datetime_partial_implicit_timestamp_s(self, util): tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))]}) - tbl.update({ - "a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0))]), - "__INDEX__": np.array([0]) - }) + tbl.update({"a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0))]), "__INDEX__": np.array([0])}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)]} def test_update_np_datetime_partial_implicit_timestamp_ms(self, util): tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))]}) - tbl.update({ - "a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0)) * 1000]), - "__INDEX__": np.array([0]) - }) + tbl.update({"a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0)) * 1000]), "__INDEX__": np.array([0])}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)]} def test_update_np_datetime_partial(self): - tbl = Table({ - "a": [np.datetime64(datetime(2019, 7, 11, 11, 0))], - "b": [1] - }, index="b") + tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))], "b": [1]}, index="b") - tbl.update({ - "a": np.array([datetime(2019, 7, 12, 11, 0)], dtype=datetime), - "b": np.array([1]) - }) + tbl.update({"a": np.array([datetime(2019, 7, 12, 11, 0)], dtype=datetime), "b": np.array([1])}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)], - "b": [1] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)], "b": [1]} def test_update_np_datetime_partial_timestamp_s(self, util): - tbl = Table({ - "a": [np.datetime64(datetime(2019, 7, 11, 11, 0))], - "idx": [1] - }, index="idx") + tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))], "idx": [1]}, index="idx") - tbl.update({ - "a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0))]), - "idx": np.array([1]) - }) + tbl.update({"a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0))]), "idx": np.array([1])}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)], - "idx": [1] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)], "idx": [1]} def test_update_np_datetime_partial_timestamp_ms(self, util): - tbl = Table({ - "a": [np.datetime64(datetime(2019, 7, 11, 11, 0))], - "idx": [1] - }, index="idx") + tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))], "idx": [1]}, index="idx") - tbl.update({ - "a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0)) * 1000]), - "idx": np.array([1]) - }) + tbl.update({"a": np.array([util.to_timestamp(datetime(2019, 7, 12, 11, 0)) * 1000]), "idx": np.array([1])}) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)], - "idx": [1] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)], "idx": [1]} def test_update_np_nonseq_partial(self): - tbl = Table({ - "a": [1, 2, 3, 4], - "b": ["a", "b", "c", "d"] - }, index="b") + tbl = Table({"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"]}, index="b") - tbl.update({ - "a": np.array([5, 6, 7]), - "b": np.array(["a", "c", "d"], dtype=object)} - ) + tbl.update({"a": np.array([5, 6, 7]), "b": np.array(["a", "c", "d"], dtype=object)}) - assert tbl.view().to_dict() == { - "a": [5, 2, 6, 7], - "b": ["a", "b", "c", "d"] - } + assert tbl.view().to_dict() == {"a": [5, 2, 6, 7], "b": ["a", "b", "c", "d"]} def test_update_np_with_none_partial(self): - tbl = Table({ - "a": [1, np.nan, 3], - "b": ["a", None, "d"] - }, index="b") + tbl = Table({"a": [1, np.nan, 3], "b": ["a", None, "d"]}, index="b") - tbl.update({ - "a": np.array([4, 5]), - "b": np.array(["a", "d"], dtype=object) - }) + tbl.update({"a": np.array([4, 5]), "b": np.array(["a", "d"], dtype=object)}) - assert tbl.view().to_dict() == { - "a": [None, 4, 5], - "b": [None, "a", "d"] # pkeys are ordered - } + assert tbl.view().to_dict() == {"a": [None, 4, 5], "b": [None, "a", "d"]} # pkeys are ordered def test_update_np_unset_partial(self): - tbl = Table({ - "a": [1, 2, 3], - "b": ["a", "b", "c"] - }, index="b") + tbl = Table({"a": [1, 2, 3], "b": ["a", "b", "c"]}, index="b") - tbl.update({ - "a": np.array([None, None]), - "b": np.array(["a", "c"], dtype=object) - }) + tbl.update({"a": np.array([None, None]), "b": np.array(["a", "c"], dtype=object)}) - assert tbl.view().to_dict() == { - "a": [None, 2, None], - "b": ["a", "b", "c"] - } + assert tbl.view().to_dict() == {"a": [None, 2, None], "b": ["a", "b", "c"]} def test_update_np_nan_partial(self): - tbl = Table({ - "a": [1, 2, 3], - "b": ["a", "b", "c"] - }, index="b") + tbl = Table({"a": [1, 2, 3], "b": ["a", "b", "c"]}, index="b") - tbl.update({ - "a": np.array([None, None]), - "b": np.array(["a", "c"], dtype=object) - }) + tbl.update({"a": np.array([None, None]), "b": np.array(["a", "c"], dtype=object)}) - assert tbl.view().to_dict() == { - "a": [None, 2, None], - "b": ["a", "b", "c"] - } + assert tbl.view().to_dict() == {"a": [None, 2, None], "b": ["a", "b", "c"]} def test_numpy_dict(self): x = {"index": [1], "a": np.empty((1,), str)} - tbl = Table({"index": int, "a": str}, index='index') + tbl = Table({"index": int, "a": str}, index="index") tbl.update({"index": np.arange(5)}) - assert tbl.view().to_dict() == { - "index": list(range(5)), - "a": [None for _ in range(5)] - } + assert tbl.view().to_dict() == {"index": list(range(5)), "a": [None for _ in range(5)]} diff --git a/python/perspective/perspective/tests/table/test_update_pandas.py b/python/perspective/perspective/tests/table/test_update_pandas.py index 3376e303cb..38bc05e43c 100644 --- a/python/perspective/perspective/tests/table/test_update_pandas.py +++ b/python/perspective/perspective/tests/table/test_update_pandas.py @@ -21,254 +21,149 @@ class TestUpdatePandas(object): def test_update_df(self): tbl = Table({"a": [1, 2, 3, 4]}) - update_data = pd.DataFrame({ - "a": [5, 6, 7, 8] - }) + update_data = pd.DataFrame({"a": [5, 6, 7, 8]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4, 5, 6, 7, 8] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4, 5, 6, 7, 8]} def test_update_df_i32_vs_i64(self): tbl = Table({"a": int}) - update_data = pd.DataFrame({ - "a": np.array([5, 6, 7, 8], dtype="int64") - }) + update_data = pd.DataFrame({"a": np.array([5, 6, 7, 8], dtype="int64")}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [5, 6, 7, 8] - } + assert tbl.view().to_dict() == {"a": [5, 6, 7, 8]} def test_update_df_bool(self): tbl = Table({"a": [True, False, True, False]}) - update_data = pd.DataFrame({ - "a": [True, False, True, False] - }) + update_data = pd.DataFrame({"a": [True, False, True, False]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [True, False, True, False, True, False, True, False] - } + assert tbl.view().to_dict() == {"a": [True, False, True, False, True, False, True, False]} def test_update_df_str(self): tbl = Table({"a": ["a", "b", "c", "d"]}) - update_data = pd.DataFrame({ - "a": ["a", "b", "c", "d"] - }) + update_data = pd.DataFrame({"a": ["a", "b", "c", "d"]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": ["a", "b", "c", "d", "a", "b", "c", "d"] - } + assert tbl.view().to_dict() == {"a": ["a", "b", "c", "d", "a", "b", "c", "d"]} def test_update_df_date(self): tbl = Table({"a": [date(2019, 7, 11)]}) - update_data = pd.DataFrame({ - "a": [date(2019, 7, 12)] - }) + update_data = pd.DataFrame({"a": [date(2019, 7, 12)]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11), datetime(2019, 7, 12)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11), datetime(2019, 7, 12)]} def test_update_df_date_timestamp(self, util): tbl = Table({"a": [date(2019, 7, 11)]}) - assert tbl.schema() == { - "a": date - } + assert tbl.schema() == {"a": date} - update_data = pd.DataFrame({ - "a": [util.to_timestamp(datetime(2019, 7, 12, 0, 0, 0))] - }) + update_data = pd.DataFrame({"a": [util.to_timestamp(datetime(2019, 7, 12, 0, 0, 0))]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11), datetime(2019, 7, 12)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11), datetime(2019, 7, 12)]} def test_update_df_datetime(self): tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))]}) - update_data = pd.DataFrame({ - "a": [datetime(2019, 7, 12, 11, 0)] - }) + update_data = pd.DataFrame({"a": [datetime(2019, 7, 12, 11, 0)]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)]} def test_update_df_datetime_timestamp_seconds(self, util): tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))]}) - update_data = pd.DataFrame({ - "a": [util.to_timestamp(datetime(2019, 7, 12, 11, 0))] - }) + update_data = pd.DataFrame({"a": [util.to_timestamp(datetime(2019, 7, 12, 11, 0))]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)]} def test_update_df_datetime_timestamp_ms(self, util): tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))]}) - update_data = pd.DataFrame({ - "a": [util.to_timestamp(datetime(2019, 7, 12, 11, 0)) * 1000] - }) + update_data = pd.DataFrame({"a": [util.to_timestamp(datetime(2019, 7, 12, 11, 0)) * 1000]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 11, 0), datetime(2019, 7, 12, 11, 0)]} def test_update_df_partial(self): - tbl = Table({ - "a": [1, 2, 3, 4], - "b": ["a", "b", "c", "d"] - }, index="b") + tbl = Table({"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"]}, index="b") - update_data = pd.DataFrame({ - "a": [5, 6, 7, 8], - "b": ["a", "b", "c", "d"] - }) + update_data = pd.DataFrame({"a": [5, 6, 7, 8], "b": ["a", "b", "c", "d"]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [5, 6, 7, 8], - "b": ["a", "b", "c", "d"] - } + assert tbl.view().to_dict() == {"a": [5, 6, 7, 8], "b": ["a", "b", "c", "d"]} def test_update_df_partial_implicit(self): tbl = Table({"a": [1, 2, 3, 4]}) - update_data = pd.DataFrame({ - "a": [5, 6, 7, 8], - "__INDEX__": [0, 1, 2, 3] - }) + update_data = pd.DataFrame({"a": [5, 6, 7, 8], "__INDEX__": [0, 1, 2, 3]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [5, 6, 7, 8] - } + assert tbl.view().to_dict() == {"a": [5, 6, 7, 8]} def test_update_df_datetime_partial(self): - tbl = Table({ - "a": [np.datetime64(datetime(2019, 7, 11, 11, 0))], - "b": [1] - }, index="b") + tbl = Table({"a": [np.datetime64(datetime(2019, 7, 11, 11, 0))], "b": [1]}, index="b") - update_data = pd.DataFrame({ - "a": [datetime(2019, 7, 12, 11, 0)], - "b": [1] - }) + update_data = pd.DataFrame({"a": [datetime(2019, 7, 12, 11, 0)], "b": [1]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 12, 11, 0)], - "b": [1] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 12, 11, 0)], "b": [1]} def test_update_df_one_col(self): - tbl = Table({ - "a": [1, 2, 3, 4], - "b": ["a", "b", "c", "d"] - }) + tbl = Table({"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"]}) - update_data = pd.DataFrame({ - "a": [5, 6, 7] - }) + update_data = pd.DataFrame({"a": [5, 6, 7]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [1, 2, 3, 4, 5, 6, 7], - "b": ["a", "b", "c", "d", None, None, None] - } + assert tbl.view().to_dict() == {"a": [1, 2, 3, 4, 5, 6, 7], "b": ["a", "b", "c", "d", None, None, None]} def test_update_df_nonseq_partial(self): - tbl = Table({ - "a": [1, 2, 3, 4], - "b": ["a", "b", "c", "d"] - }, index="b") + tbl = Table({"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"]}, index="b") - update_data = pd.DataFrame({ - "a": [5, 6, 7], - "b": ["a", "c", "d"] - }) + update_data = pd.DataFrame({"a": [5, 6, 7], "b": ["a", "c", "d"]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [5, 2, 6, 7], - "b": ["a", "b", "c", "d"] - } + assert tbl.view().to_dict() == {"a": [5, 2, 6, 7], "b": ["a", "b", "c", "d"]} def test_update_df_with_none_partial(self): - tbl = Table({ - "a": [1, np.nan, 3], - "b": ["a", None, "d"] - }, index="b") + tbl = Table({"a": [1, np.nan, 3], "b": ["a", None, "d"]}, index="b") - update_data = pd.DataFrame({ - "a": [4, 5], - "b": ["a", "d"] - }) + update_data = pd.DataFrame({"a": [4, 5], "b": ["a", "d"]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [None, 4, 5], - "b": [None, "a", "d"] # pkeys are ordered - } + assert tbl.view().to_dict() == {"a": [None, 4, 5], "b": [None, "a", "d"]} # pkeys are ordered def test_update_df_unset_partial(self): - tbl = Table({ - "a": [1, 2, 3], - "b": ["a", "b", "c"] - }, index="b") + tbl = Table({"a": [1, 2, 3], "b": ["a", "b", "c"]}, index="b") - update_data = pd.DataFrame({ - "a": [None, None], - "b": ["a", "c"] - }) + update_data = pd.DataFrame({"a": [None, None], "b": ["a", "c"]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [None, 2, None], - "b": ["a", "b", "c"] - } + assert tbl.view().to_dict() == {"a": [None, 2, None], "b": ["a", "b", "c"]} def test_update_df_nan_partial(self): - tbl = Table({ - "a": [1, 2, 3], - "b": ["a", "b", "c"] - }, index="b") + tbl = Table({"a": [1, 2, 3], "b": ["a", "b", "c"]}, index="b") - update_data = pd.DataFrame({ - "a": [None, None], - "b": ["a", "c"] - }) + update_data = pd.DataFrame({"a": [None, None], "b": ["a", "c"]}) tbl.update(update_data) - assert tbl.view().to_dict() == { - "a": [None, 2, None], - "b": ["a", "b", "c"] - } + assert tbl.view().to_dict() == {"a": [None, 2, None], "b": ["a", "b", "c"]} diff --git a/python/perspective/perspective/tests/table/test_view.py b/python/perspective/perspective/tests/table/test_view.py index 00a157aced..bdd2fb2a84 100644 --- a/python/perspective/perspective/tests/table/test_view.py +++ b/python/perspective/perspective/tests/table/test_view.py @@ -32,10 +32,7 @@ def test_view_zero(self): view = tbl.view() assert view.num_rows() == 2 assert view.num_columns() == 2 - assert view.schema() == { - "a": int, - "b": int - } + assert view.schema() == {"a": int, "b": int} assert view.to_records() == data def test_view_one(self): @@ -44,15 +41,8 @@ def test_view_one(self): view = tbl.view(group_by=["a"]) assert view.num_rows() == 3 assert view.num_columns() == 2 - assert view.schema() == { - "a": int, - "b": int - } - assert view.to_records() == [ - {"__ROW_PATH__": [], "a": 4, "b": 6}, - {"__ROW_PATH__": [1], "a": 1, "b": 2}, - {"__ROW_PATH__": [3], "a": 3, "b": 4} - ] + assert view.schema() == {"a": int, "b": int} + assert view.to_records() == [{"__ROW_PATH__": [], "a": 4, "b": 6}, {"__ROW_PATH__": [1], "a": 1, "b": 2}, {"__ROW_PATH__": [3], "a": 3, "b": 4}] def test_view_two(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] @@ -60,14 +50,11 @@ def test_view_two(self): view = tbl.view(group_by=["a"], split_by=["b"]) assert view.num_rows() == 3 assert view.num_columns() == 4 - assert view.schema() == { - "a": int, - "b": int - } + assert view.schema() == {"a": int, "b": int} assert view.to_records() == [ {"2|a": 1, "2|b": 2, "4|a": 3, "4|b": 4, "__ROW_PATH__": []}, {"2|a": 1, "2|b": 2, "4|a": None, "4|b": None, "__ROW_PATH__": [1]}, - {"2|a": None, "2|b": None, "4|a": 3, "4|b": 4, "__ROW_PATH__": [3]} + {"2|a": None, "2|b": None, "4|a": 3, "4|b": 4, "__ROW_PATH__": [3]}, ] def test_view_two_column_only(self): @@ -76,126 +63,83 @@ def test_view_two_column_only(self): view = tbl.view(split_by=["b"]) assert view.num_rows() == 2 assert view.num_columns() == 4 - assert view.schema() == { - "a": int, - "b": int - } - assert view.to_records() == [ - {"2|a": 1, "2|b": 2, "4|a": None, "4|b": None}, - {"2|a": None, "2|b": None, "4|a": 3, "4|b": 4} - ] + assert view.schema() == {"a": int, "b": int} + assert view.to_records() == [{"2|a": 1, "2|b": 2, "4|a": None, "4|b": None}, {"2|a": None, "2|b": None, "4|a": 3, "4|b": 4}] # column path def test_view_column_path_zero(self): - data = { - "a": [1, 2, 3], - "b": [1.5, 2.5, 3.5] - } + data = {"a": [1, 2, 3], "b": [1.5, 2.5, 3.5]} tbl = Table(data) view = tbl.view() paths = view.column_paths() assert paths == ["a", "b"] def test_view_column_path_zero_schema(self): - data = { - "a": int, - "b": float - } + data = {"a": int, "b": float} tbl = Table(data) view = tbl.view() paths = view.column_paths() assert paths == ["a", "b"] def test_view_column_path_zero_hidden(self): - data = { - "a": [1, 2, 3], - "b": [1.5, 2.5, 3.5] - } + data = {"a": [1, 2, 3], "b": [1.5, 2.5, 3.5]} tbl = Table(data) view = tbl.view(columns=["b"]) paths = view.column_paths() assert paths == ["b"] def test_view_column_path_zero_respects_order(self): - data = { - "a": [1, 2, 3], - "b": [1.5, 2.5, 3.5] - } + data = {"a": [1, 2, 3], "b": [1.5, 2.5, 3.5]} tbl = Table(data) view = tbl.view(columns=["b", "a"]) paths = view.column_paths() assert paths == ["b", "a"] def test_view_column_path_one(self): - data = { - "a": [1, 2, 3], - "b": [1.5, 2.5, 3.5] - } + data = {"a": [1, 2, 3], "b": [1.5, 2.5, 3.5]} tbl = Table(data) view = tbl.view(group_by=["a"]) paths = view.column_paths() assert paths == ["__ROW_PATH__", "a", "b"] def test_view_column_path_one_numeric_names(self): - data = { - "a": [1, 2, 3], - "b": [1.5, 2.5, 3.5], - "1234": [5, 6, 7] - } + data = {"a": [1, 2, 3], "b": [1.5, 2.5, 3.5], "1234": [5, 6, 7]} tbl = Table(data) view = tbl.view(group_by=["a"], columns=["b", "1234", "a"]) paths = view.column_paths() assert paths == ["__ROW_PATH__", "b", "1234", "a"] def test_view_column_path_two(self): - data = { - "a": [1, 2, 3], - "b": [1.5, 2.5, 3.5] - } + data = {"a": [1, 2, 3], "b": [1.5, 2.5, 3.5]} tbl = Table(data) view = tbl.view(group_by=["a"], split_by=["b"]) paths = view.column_paths() assert paths == ["__ROW_PATH__", "1.5|a", "1.5|b", "2.5|a", "2.5|b", "3.5|a", "3.5|b"] def test_view_column_path_two_column_only(self): - data = { - "a": [1, 2, 3], - "b": [1.5, 2.5, 3.5] - } + data = {"a": [1, 2, 3], "b": [1.5, 2.5, 3.5]} tbl = Table(data) view = tbl.view(split_by=["b"]) paths = view.column_paths() assert paths == ["1.5|a", "1.5|b", "2.5|a", "2.5|b", "3.5|a", "3.5|b"] def test_view_column_path_hidden_sort(self): - data = { - "a": [1, 2, 3], - "b": [1.5, 2.5, 3.5], - "c": [3, 2, 1] - } + data = {"a": [1, 2, 3], "b": [1.5, 2.5, 3.5], "c": [3, 2, 1]} tbl = Table(data) view = tbl.view(columns=["a", "b"], sort=[["c", "desc"]]) paths = view.column_paths() assert paths == ["a", "b"] def test_view_column_path_hidden_col_sort(self): - data = { - "a": [1, 2, 3], - "b": [1.5, 2.5, 3.5], - "c": [3, 2, 1] - } + data = {"a": [1, 2, 3], "b": [1.5, 2.5, 3.5], "c": [3, 2, 1]} tbl = Table(data) view = tbl.view(split_by=["a"], columns=["a", "b"], sort=[["c", "col desc"]]) paths = view.column_paths() assert paths == ["1|a", "1|b", "2|a", "2|b", "3|a", "3|b"] def test_view_column_path_pivot_by_bool(self): - data = { - "a": [1, 2, 3], - "b": [True, False, True], - "c": [3, 2, 1] - } + data = {"a": [1, 2, 3], "b": [True, False, True], "c": [3, 2, 1]} tbl = Table(data) view = tbl.view(split_by=["b"], columns=["a", "b", "c"]) paths = view.column_paths() @@ -207,43 +151,25 @@ def test_string_view_schema(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - assert view.schema(as_string=True) == { - "a": "integer", - "b": "integer" - } + assert view.schema(as_string=True) == {"a": "integer", "b": "integer"} def test_zero_view_schema(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) view = tbl.view() - assert view.schema() == { - "a": int, - "b": int - } + assert view.schema() == {"a": int, "b": int} def test_one_view_schema(self): data = [{"a": "abc", "b": 2}, {"a": "abc", "b": 4}] tbl = Table(data) view = tbl.view(group_by=["a"], aggregates={"a": "distinct count"}) - assert view.schema() == { - "a": int, - "b": int - } + assert view.schema() == {"a": int, "b": int} def test_two_view_schema(self): data = [{"a": "abc", "b": "def"}, {"a": "abc", "b": "def"}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - split_by=["b"], - aggregates={ - "a": "count", - "b": "count" - }) - assert view.schema() == { - "a": int, - "b": int - } + view = tbl.view(group_by=["a"], split_by=["b"], aggregates={"a": "count", "b": "count"}) + assert view.schema() == {"a": int, "b": int} # aggregates and column specification @@ -259,14 +185,7 @@ def test_view_no_columns_pivoted(self): tbl = Table(data) view = tbl.view(group_by=["a"], columns=[]) assert view.num_columns() == 0 - assert view.to_records() == [ - { - "__ROW_PATH__": [] - }, { - "__ROW_PATH__": [1] - }, { - "__ROW_PATH__": [3] - }] + assert view.to_records() == [{"__ROW_PATH__": []}, {"__ROW_PATH__": [1]}, {"__ROW_PATH__": [3]}] def test_view_specific_column(self): data = [{"a": 1, "b": 2, "c": 3, "d": 4}, {"a": 3, "b": 4, "c": 5, "d": 6}] @@ -282,44 +201,24 @@ def test_view_column_order(self): assert view.to_records() == [{"b": 2, "a": 1}, {"b": 4, "a": 3}] def test_view_dataframe_column_order(self): - table = Table(pd.DataFrame({ - "0.1": [5, 6, 7, 8], - "-0.05": [5, 6, 7, 8], - "0.0": [1, 2, 3, 4], - "-0.1": [1, 2, 3, 4], - "str": ["a", "b", "c", "d"] - })) - view = table.view( - columns=["-0.1", "-0.05", "0.0", "0.1"], group_by=["str"]) - assert view.column_paths() == [ - "__ROW_PATH__", "-0.1", "-0.05", "0.0", "0.1"] + table = Table(pd.DataFrame({"0.1": [5, 6, 7, 8], "-0.05": [5, 6, 7, 8], "0.0": [1, 2, 3, 4], "-0.1": [1, 2, 3, 4], "str": ["a", "b", "c", "d"]})) + view = table.view(columns=["-0.1", "-0.05", "0.0", "0.1"], group_by=["str"]) + assert view.column_paths() == ["__ROW_PATH__", "-0.1", "-0.05", "0.0", "0.1"] def test_view_aggregate_order_with_columns(self): - '''If `columns` is provided, order is always guaranteed.''' + """If `columns` is provided, order is always guaranteed.""" data = [{"a": 1, "b": 2, "c": 3, "d": 4}, {"a": 3, "b": 4, "c": 5, "d": 6}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - columns=["a", "b", "c", "d"], - aggregates={"d": "avg", "c": "avg", "b": "last", "a": "last"} - ) + view = tbl.view(group_by=["a"], columns=["a", "b", "c", "d"], aggregates={"d": "avg", "c": "avg", "b": "last", "a": "last"}) order = ["__ROW_PATH__", "a", "b", "c", "d"] assert view.column_paths() == order def test_view_df_aggregate_order_with_columns(self): - '''If `columns` is provided, order is always guaranteed.''' - data = pd.DataFrame({ - "a": [1, 2, 3], - "b": [2, 3, 4], - "c": [3, 4, 5], - "d": [4, 5, 6] - }, columns=["d", "a", "c", "b"]) + """If `columns` is provided, order is always guaranteed.""" + data = pd.DataFrame({"a": [1, 2, 3], "b": [2, 3, 4], "c": [3, 4, 5], "d": [4, 5, 6]}, columns=["d", "a", "c", "b"]) tbl = Table(data) - view = tbl.view( - group_by=["a"], - aggregates={"d": "avg", "c": "avg", "b": "last", "a": "last"} - ) + view = tbl.view(group_by=["a"], aggregates={"d": "avg", "c": "avg", "b": "last", "a": "last"}) order = ["__ROW_PATH__", "index", "d", "a", "c", "b"] assert view.column_paths() == order @@ -327,29 +226,18 @@ def test_view_df_aggregate_order_with_columns(self): def test_view_aggregates_with_no_columns(self): data = [{"a": 1, "b": 2, "c": 3, "d": 4}, {"a": 3, "b": 4, "c": 5, "d": 6}] tbl = Table(data) - view = tbl.view( - group_by=["a"], - aggregates={"c": "avg", "a": "last"}, - columns=[] - ) + view = tbl.view(group_by=["a"], aggregates={"c": "avg", "a": "last"}, columns=[]) assert view.column_paths() == ["__ROW_PATH__"] - assert view.to_records() == [ - {"__ROW_PATH__": []}, - {"__ROW_PATH__": [1]}, - {"__ROW_PATH__": [3]} - ] + assert view.to_records() == [{"__ROW_PATH__": []}, {"__ROW_PATH__": [1]}, {"__ROW_PATH__": [3]}] def test_view_aggregates_default_column_order(self): - '''Order of columns are entirely determined by the `columns` kwarg. If + """Order of columns are entirely determined by the `columns` kwarg. If it is not provided, order of columns is default based on the order - of table.columns().''' + of table.columns().""" data = [{"a": 1, "b": 2, "c": 3, "d": 4}, {"a": 3, "b": 4, "c": 5, "d": 6}] tbl = Table(data) - cols = tbl.columns(); - view = tbl.view( - group_by=["a"], - aggregates={"c": "avg", "a": "last"} - ) + cols = tbl.columns() + view = tbl.view(group_by=["a"], aggregates={"c": "avg", "a": "last"}) order = ["__ROW_PATH__"] + cols assert view.column_paths() == order @@ -376,9 +264,7 @@ def test_view_group_by_datetime_row_paths_are_same_as_data(self): if len(rp) > 0: assert rp[0] == datetime(2019, 7, 11, 12, 30) - assert tbl.view().to_dict() == { - "a": [datetime(2019, 7, 11, 12, 30)], "b": [1] - } + assert tbl.view().to_dict() == {"a": [datetime(2019, 7, 11, 12, 30)], "b": [1]} def test_view_split_by_datetime_names_utc(self): """Tests column paths for datetimes in UTC. Timezone-related tests are @@ -413,137 +299,57 @@ def test_view_split_by_datetime_names_max(self): def test_view_aggregate_int(self): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] tbl = Table(data) - view = tbl.view( - aggregates={"a": "avg"}, - group_by=["a"] - ) - assert view.to_records() == [ - {"__ROW_PATH__": [], "a": 2.0, "b": 6}, - {"__ROW_PATH__": [1], "a": 1.0, "b": 2}, - {"__ROW_PATH__": [3], "a": 3.0, "b": 4} - ] + view = tbl.view(aggregates={"a": "avg"}, group_by=["a"]) + assert view.to_records() == [{"__ROW_PATH__": [], "a": 2.0, "b": 6}, {"__ROW_PATH__": [1], "a": 1.0, "b": 2}, {"__ROW_PATH__": [3], "a": 3.0, "b": 4}] def test_view_aggregate_str(self): data = [{"a": "abc", "b": 2}, {"a": "def", "b": 4}] tbl = Table(data) - view = tbl.view( - aggregates={"a": "count"}, - group_by=["a"] - ) - assert view.to_records() == [ - {"__ROW_PATH__": [], "a": 2, "b": 6}, - {"__ROW_PATH__": ["abc"], "a": 1, "b": 2}, - {"__ROW_PATH__": ["def"], "a": 1, "b": 4} - ] + view = tbl.view(aggregates={"a": "count"}, group_by=["a"]) + assert view.to_records() == [{"__ROW_PATH__": [], "a": 2, "b": 6}, {"__ROW_PATH__": ["abc"], "a": 1, "b": 2}, {"__ROW_PATH__": ["def"], "a": 1, "b": 4}] def test_view_aggregate_datetime(self): data = [{"a": datetime(2019, 10, 1, 11, 30)}, {"a": datetime(2019, 10, 1, 11, 30)}] tbl = Table(data) - view = tbl.view( - aggregates={"a": "distinct count"}, - group_by=["a"] - ) - assert view.to_records() == [ - {"__ROW_PATH__": [], "a": 1}, - {"__ROW_PATH__": [datetime(2019, 10, 1, 11, 30)], "a": 1} - ] + view = tbl.view(aggregates={"a": "distinct count"}, group_by=["a"]) + assert view.to_records() == [{"__ROW_PATH__": [], "a": 1}, {"__ROW_PATH__": [datetime(2019, 10, 1, 11, 30)], "a": 1}] def test_view_aggregate_datetime_leading_zeroes(self): data = [{"a": datetime(2019, 1, 1, 5, 5, 5)}, {"a": datetime(2019, 1, 1, 5, 5, 5)}] tbl = Table(data) - view = tbl.view( - aggregates={"a": "distinct count"}, - group_by=["a"] - ) - assert view.to_records() == [ - {"__ROW_PATH__": [], "a": 1}, - {"__ROW_PATH__": [datetime(2019, 1, 1, 5, 5, 5)], "a": 1} - ] + view = tbl.view(aggregates={"a": "distinct count"}, group_by=["a"]) + assert view.to_records() == [{"__ROW_PATH__": [], "a": 1}, {"__ROW_PATH__": [datetime(2019, 1, 1, 5, 5, 5)], "a": 1}] def test_view_aggregate_mean(self): - data = [ - {"a": "a", "x": 1, "y": 200}, - {"a": "a", "x": 2, "y": 100}, - {"a": "a", "x": 3, "y": None} - ] + data = [{"a": "a", "x": 1, "y": 200}, {"a": "a", "x": 2, "y": 100}, {"a": "a", "x": 3, "y": None}] tbl = Table(data) - view = tbl.view( - aggregates={"y": "mean"}, - group_by=["a"], - columns=['y'] - ) - assert view.to_records() == [ - {"__ROW_PATH__": [], "y": 300 / 2}, - {"__ROW_PATH__": ["a"], "y": 300 / 2} - ] + view = tbl.view(aggregates={"y": "mean"}, group_by=["a"], columns=["y"]) + assert view.to_records() == [{"__ROW_PATH__": [], "y": 300 / 2}, {"__ROW_PATH__": ["a"], "y": 300 / 2}] def test_view_aggregate_mean_from_schema(self): - data = [ - {"a": "a", "x": 1, "y": 200}, - {"a": "a", "x": 2, "y": 100}, - {"a": "a", "x": 3, "y": None} - ] - tbl = Table({ - "a": str, - "x": int, - "y": float - }) - view = tbl.view( - aggregates={"y": "mean"}, - group_by=["a"], - columns=['y'] - ) + data = [{"a": "a", "x": 1, "y": 200}, {"a": "a", "x": 2, "y": 100}, {"a": "a", "x": 3, "y": None}] + tbl = Table({"a": str, "x": int, "y": float}) + view = tbl.view(aggregates={"y": "mean"}, group_by=["a"], columns=["y"]) tbl.update(data) - assert view.to_records() == [ - {"__ROW_PATH__": [], "y": 300 / 2}, - {"__ROW_PATH__": ["a"], "y": 300 / 2} - ] + assert view.to_records() == [{"__ROW_PATH__": [], "y": 300 / 2}, {"__ROW_PATH__": ["a"], "y": 300 / 2}] def test_view_aggregate_weighted_mean(self): - data = [ - {"a": "a", "x": 1, "y": 200}, - {"a": "a", "x": 2, "y": 100}, - {"a": "a", "x": 3, "y": None} - ] + data = [{"a": "a", "x": 1, "y": 200}, {"a": "a", "x": 2, "y": 100}, {"a": "a", "x": 3, "y": None}] tbl = Table(data) - view = tbl.view( - aggregates={"y": ["weighted mean", "x"]}, - group_by=["a"], - columns=['y'] - ) - assert view.to_records() == [ - {"__ROW_PATH__": [], "y": (1.0 * 200 + 2 * 100) / (1.0 + 2)}, - {"__ROW_PATH__": ["a"], "y": (1.0 * 200 + 2 * 100) / (1.0 + 2)} - ] + view = tbl.view(aggregates={"y": ["weighted mean", "x"]}, group_by=["a"], columns=["y"]) + assert view.to_records() == [{"__ROW_PATH__": [], "y": (1.0 * 200 + 2 * 100) / (1.0 + 2)}, {"__ROW_PATH__": ["a"], "y": (1.0 * 200 + 2 * 100) / (1.0 + 2)}] def test_view_aggregate_weighted_mean_with_negative_weights(self): - data = [ - {"a": "a", "x": 1, "y": 200}, - {"a": "a", "x": -2, "y": 100}, - {"a": "a", "x": 3, "y": None} - ] + data = [{"a": "a", "x": 1, "y": 200}, {"a": "a", "x": -2, "y": 100}, {"a": "a", "x": 3, "y": None}] tbl = Table(data) - view = tbl.view( - aggregates={"y": ["weighted mean", "x"]}, - group_by=["a"], - columns=['y'] - ) - assert view.to_records() == [ - {"__ROW_PATH__": [], "y": (1 * 200 + (-2) * 100) / (1 - 2)}, - {"__ROW_PATH__": ["a"], "y": (1 * 200 + (-2) * 100) / (1 - 2)} - ] + view = tbl.view(aggregates={"y": ["weighted mean", "x"]}, group_by=["a"], columns=["y"]) + assert view.to_records() == [{"__ROW_PATH__": [], "y": (1 * 200 + (-2) * 100) / (1 - 2)}, {"__ROW_PATH__": ["a"], "y": (1 * 200 + (-2) * 100) / (1 - 2)}] def test_view_variance(self): - data = { - "x": list(np.random.rand(10)), - "y": ["a" for _ in range(10)] - } + data = {"x": list(np.random.rand(10)), "y": ["a" for _ in range(10)]} table = Table(data) - view = table.view( - aggregates={"x": "var"}, - group_by=["y"] - ) + view = table.view(aggregates={"x": "var"}, group_by=["y"]) result = view.to_dict() expected = np.var(data["x"]) @@ -551,15 +357,9 @@ def test_view_variance(self): assert result["x"] == approx([expected, expected]) def test_view_variance_multi(self): - data = { - "a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], - "b": [1 if i % 2 == 0 else 0 for i in range(10)] - } + data = {"a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], "b": [1 if i % 2 == 0 else 0 for i in range(10)]} table = Table(data) - view = table.view( - aggregates={"a": "var"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "var"}, group_by=["b"]) result = view.to_columns() expected_total = np.var(data["a"]) @@ -569,11 +369,7 @@ def test_view_variance_multi(self): assert result["a"] == approx([expected_total, expected_zero, expected_one]) def test_view_variance_update_none(self): - data = { - "a": [0.1, 0.5, None, 0.8], - "b": [0, 1, 0, 1], - "c": [1, 2, 3, 4] - } + data = {"a": [0.1, 0.5, None, 0.8], "b": [0, 1, 0, 1], "c": [1, 2, 3, 4]} table = Table(data, index="c") view = table.view(columns=["a"], group_by=["b"], aggregates={"a": "var"}) result = view.to_columns() @@ -581,18 +377,12 @@ def test_view_variance_update_none(self): assert result["a"][1] is None assert result["a"][2] == approx(np.var([0.5, 0.8])) - table.update({ - "a": [0.3], - "c": [3] - }) + table.update({"a": [0.3], "c": [3]}) result = view.to_columns() assert result["a"] == approx([np.var([0.1, 0.5, 0.3, 0.8]), np.var([0.1, 0.3]), np.var([0.5, 0.8])]) - table.update({ - "a": [None], - "c": [1] - }) + table.update({"a": [None], "c": [1]}) result = view.to_columns() assert result["a"][0] == approx(np.var([0.5, 0.3, 0.8])) @@ -600,15 +390,9 @@ def test_view_variance_update_none(self): assert result["a"][2] == approx(np.var([0.5, 0.8])) def test_view_variance_multi_update(self): - data = { - "a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], - "b": [1 if i % 2 == 0 else 0 for i in range(10)] - } + data = {"a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], "b": [1 if i % 2 == 0 else 0 for i in range(10)]} table = Table(data) - view = table.view( - aggregates={"a": "var"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "var"}, group_by=["b"]) result = view.to_columns() expected_total = data["a"] @@ -618,10 +402,7 @@ def test_view_variance_multi_update(self): assert result["a"] == approx([np.var(expected_total), np.var(expected_zero), np.var(expected_one)]) # 2 here should result in null var because the group size is 1 - update_data = { - "a": [15.12, 9.102, 0.99, 12.8], - "b": [1, 0, 1, 2] - } + update_data = {"a": [15.12, 9.102, 0.99, 12.8], "b": [1, 0, 1, 2]} table.update(update_data) result = view.to_columns() @@ -634,15 +415,9 @@ def test_view_variance_multi_update(self): assert result["a"][-1] is None def test_view_variance_multi_update_delta(self): - data = { - "a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], - "b": [1 if i % 2 == 0 else 0 for i in range(10)] - } + data = {"a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], "b": [1 if i % 2 == 0 else 0 for i in range(10)]} table = Table(data) - view = table.view( - aggregates={"a": "var"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "var"}, group_by=["b"]) result = view.to_columns() expected_total = data["a"] @@ -652,10 +427,7 @@ def test_view_variance_multi_update_delta(self): assert result["a"] == approx([np.var(expected_total), np.var(expected_zero), np.var(expected_one)]) # 2 here should result in null var because the group size is 1 - update_data = { - "a": [15.12, 9.102, 0.99, 12.8], - "b": [1, 0, 1, 2] - } + update_data = {"a": [15.12, 9.102, 0.99, 12.8], "b": [1, 0, 1, 2]} def cb1(port_id, delta): table2 = Table(delta) @@ -685,18 +457,10 @@ def cb1(port_id, delta): table.update(update_data) - def test_view_variance_multi_update_indexed(self): - data = { - "a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], - "b": [1 if i % 2 == 0 else 0 for i in range(10)], - "c": [i for i in range(10)] - } + data = {"a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], "b": [1 if i % 2 == 0 else 0 for i in range(10)], "c": [i for i in range(10)]} table = Table(data, index="c") - view = table.view( - aggregates={"a": "var"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "var"}, group_by=["b"]) result = view.to_columns() expected_total = data["a"] @@ -706,11 +470,7 @@ def test_view_variance_multi_update_indexed(self): assert result["a"] == approx([np.var(expected_total), np.var(expected_zero), np.var(expected_one)]) # "b" = 2 here should result in null var because the group size is 1 - update_data = { - "a": [15.12, 9.102, 0.99, 12.8], - "b": [1, 0, 1, 2], - "c": [1, 5, 2, 7] - } + update_data = {"a": [15.12, 9.102, 0.99, 12.8], "b": [1, 0, 1, 2], "c": [1, 5, 2, 7]} table.update(update_data) @@ -734,16 +494,9 @@ def test_view_variance_multi_update_indexed(self): assert result["a"][-1] is None def test_view_variance_multi_update_indexed_delta(self): - data = { - "a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], - "b": [1 if i % 2 == 0 else 0 for i in range(10)], - "c": [i for i in range(10)] - } + data = {"a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], "b": [1 if i % 2 == 0 else 0 for i in range(10)], "c": [i for i in range(10)]} table = Table(data, index="c") - view = table.view( - aggregates={"a": "var", "b": "last", "c": "last"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "var", "b": "last", "c": "last"}, group_by=["b"]) result = view.to_columns() expected_total = data["a"] @@ -753,11 +506,7 @@ def test_view_variance_multi_update_indexed_delta(self): assert result["a"] == approx([np.var(expected_total), np.var(expected_zero), np.var(expected_one)]) # 2 here should result in null var because the group size is 1 - update_data = { - "a": [15.12, 9.102, 0.99, 12.8], - "b": [1, 0, 1, 2], - "c": [0, 4, 1, 6] - } + update_data = {"a": [15.12, 9.102, 0.99, 12.8], "b": [1, 0, 1, 2], "c": [0, 4, 1, 6]} def cb1(port_id, delta): table2 = Table(delta) @@ -790,47 +539,29 @@ def cb1(port_id, delta): table.update(update_data) def test_view_variance_less_than_two(self): - data = { - "a": list(np.random.rand(10)), - "b": [i for i in range(10)] - } + data = {"a": list(np.random.rand(10)), "b": [i for i in range(10)]} table = Table(data) - view = table.view( - aggregates={"a": "var"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "var"}, group_by=["b"]) result = view.to_columns() assert result["a"][0] == approx(np.var(data["a"])) assert result["a"][1:] == [None] * 10 def test_view_variance_normal_distribution(self): - data = { - "a": list(np.random.standard_normal(100)), - "b": [1] * 100 - } + data = {"a": list(np.random.standard_normal(100)), "b": [1] * 100} table = Table(data) - view = table.view( - aggregates={"a": "var"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "var"}, group_by=["b"]) result = view.to_columns() assert result["a"] == approx([np.var(data["a"]), np.var(data["a"])]) def test_view_standard_deviation(self): - data = { - "x": list(np.random.rand(10)), - "y": ["a" for _ in range(10)] - } + data = {"x": list(np.random.rand(10)), "y": ["a" for _ in range(10)]} table = Table(data) - view = table.view( - aggregates={"x": "stddev"}, - group_by=["y"] - ) + view = table.view(aggregates={"x": "stddev"}, group_by=["y"]) result = view.to_dict() expected = np.std(data["x"]) @@ -838,15 +569,9 @@ def test_view_standard_deviation(self): assert result["x"] == approx([expected, expected]) def test_view_standard_deviation_multi(self): - data = { - "a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], - "b": [1 if i % 2 == 0 else 0 for i in range(10)] - } + data = {"a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], "b": [1 if i % 2 == 0 else 0 for i in range(10)]} table = Table(data) - view = table.view( - aggregates={"a": "stddev"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "stddev"}, group_by=["b"]) result = view.to_columns() expected_total = np.std(data["a"]) @@ -856,11 +581,7 @@ def test_view_standard_deviation_multi(self): assert result["a"] == approx([expected_total, expected_zero, expected_one]) def test_view_standard_deviation_update_none(self): - data = { - "a": [0.1, 0.5, None, 0.8], - "b": [0, 1, 0, 1], - "c": [1, 2, 3, 4] - } + data = {"a": [0.1, 0.5, None, 0.8], "b": [0, 1, 0, 1], "c": [1, 2, 3, 4]} table = Table(data, index="c") view = table.view(columns=["a"], group_by=["b"], aggregates={"a": "stddev"}) result = view.to_columns() @@ -868,18 +589,12 @@ def test_view_standard_deviation_update_none(self): assert result["a"][1] is None assert result["a"][2] == approx(np.std([0.5, 0.8])) - table.update({ - "a": [0.3], - "c": [3] - }) + table.update({"a": [0.3], "c": [3]}) result = view.to_columns() assert result["a"] == approx([np.std([0.1, 0.5, 0.3, 0.8]), np.std([0.1, 0.3]), np.std([0.5, 0.8])]) - table.update({ - "a": [None], - "c": [1] - }) + table.update({"a": [None], "c": [1]}) result = view.to_columns() assert result["a"][0] == approx(np.std([0.5, 0.3, 0.8])) @@ -887,15 +602,9 @@ def test_view_standard_deviation_update_none(self): assert result["a"][2] == approx(np.std([0.5, 0.8])) def test_view_standard_deviation_multi_update(self): - data = { - "a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], - "b": [1 if i % 2 == 0 else 0 for i in range(10)] - } + data = {"a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], "b": [1 if i % 2 == 0 else 0 for i in range(10)]} table = Table(data) - view = table.view( - aggregates={"a": "stddev"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "stddev"}, group_by=["b"]) result = view.to_columns() expected_total = data["a"] @@ -905,10 +614,7 @@ def test_view_standard_deviation_multi_update(self): assert result["a"] == approx([np.std(expected_total), np.std(expected_zero), np.std(expected_one)]) # 2 here should result in null stddev because the group size is 1 - update_data = { - "a": [15.12, 9.102, 0.99, 12.8], - "b": [1, 0, 1, 2] - } + update_data = {"a": [15.12, 9.102, 0.99, 12.8], "b": [1, 0, 1, 2]} table.update(update_data) result = view.to_columns() @@ -921,15 +627,9 @@ def test_view_standard_deviation_multi_update(self): assert result["a"][-1] is None def test_view_standard_deviation_multi_update_delta(self): - data = { - "a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], - "b": [1 if i % 2 == 0 else 0 for i in range(10)] - } + data = {"a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], "b": [1 if i % 2 == 0 else 0 for i in range(10)]} table = Table(data) - view = table.view( - aggregates={"a": "stddev"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "stddev"}, group_by=["b"]) result = view.to_columns() expected_total = data["a"] @@ -939,10 +639,7 @@ def test_view_standard_deviation_multi_update_delta(self): assert result["a"] == approx([np.std(expected_total), np.std(expected_zero), np.std(expected_one)]) # 2 here should result in null stddev because the group size is 1 - update_data = { - "a": [15.12, 9.102, 0.99, 12.8], - "b": [1, 0, 1, 2] - } + update_data = {"a": [15.12, 9.102, 0.99, 12.8], "b": [1, 0, 1, 2]} def cb1(port_id, delta): table2 = Table(delta) @@ -972,18 +669,10 @@ def cb1(port_id, delta): table.update(update_data) - def test_view_standard_deviation_multi_update_indexed(self): - data = { - "a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], - "b": [1 if i % 2 == 0 else 0 for i in range(10)], - "c": [i for i in range(10)] - } + data = {"a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], "b": [1 if i % 2 == 0 else 0 for i in range(10)], "c": [i for i in range(10)]} table = Table(data, index="c") - view = table.view( - aggregates={"a": "stddev"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "stddev"}, group_by=["b"]) result = view.to_columns() expected_total = data["a"] @@ -993,11 +682,7 @@ def test_view_standard_deviation_multi_update_indexed(self): assert result["a"] == approx([np.std(expected_total), np.std(expected_zero), np.std(expected_one)]) # "b" = 2 here should result in null stddev because the group size is 1 - update_data = { - "a": [15.12, 9.102, 0.99, 12.8], - "b": [1, 0, 1, 2], - "c": [1, 5, 2, 7] - } + update_data = {"a": [15.12, 9.102, 0.99, 12.8], "b": [1, 0, 1, 2], "c": [1, 5, 2, 7]} table.update(update_data) @@ -1021,16 +706,9 @@ def test_view_standard_deviation_multi_update_indexed(self): assert result["a"][-1] is None def test_view_standard_deviation_multi_update_indexed_delta(self): - data = { - "a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], - "b": [1 if i % 2 == 0 else 0 for i in range(10)], - "c": [i for i in range(10)] - } + data = {"a": [91.96, 258.576, 29.6, 243.16, 36.24, 25.248, 79.99, 206.1, 31.5, 55.6], "b": [1 if i % 2 == 0 else 0 for i in range(10)], "c": [i for i in range(10)]} table = Table(data, index="c") - view = table.view( - aggregates={"a": "stddev", "b": "last", "c": "last"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "stddev", "b": "last", "c": "last"}, group_by=["b"]) result = view.to_columns() expected_total = data["a"] @@ -1040,11 +718,7 @@ def test_view_standard_deviation_multi_update_indexed_delta(self): assert result["a"] == approx([np.std(expected_total), np.std(expected_zero), np.std(expected_one)]) # 2 here should result in null stddev because the group size is 1 - update_data = { - "a": [15.12, 9.102, 0.99, 12.8], - "b": [1, 0, 1, 2], - "c": [0, 4, 1, 6] - } + update_data = {"a": [15.12, 9.102, 0.99, 12.8], "b": [1, 0, 1, 2], "c": [0, 4, 1, 6]} def cb1(port_id, delta): table2 = Table(delta) @@ -1077,32 +751,20 @@ def cb1(port_id, delta): table.update(update_data) def test_view_standard_deviation_less_than_two(self): - data = { - "a": list(np.random.rand(10)), - "b": [i for i in range(10)] - } + data = {"a": list(np.random.rand(10)), "b": [i for i in range(10)]} table = Table(data) - view = table.view( - aggregates={"a": "stddev"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "stddev"}, group_by=["b"]) result = view.to_columns() assert result["a"][0] == approx(np.std(data["a"])) assert result["a"][1:] == [None] * 10 def test_view_standard_deviation_normal_distribution(self): - data = { - "a": list(np.random.standard_normal(100)), - "b": [1] * 100 - } + data = {"a": list(np.random.standard_normal(100)), "b": [1] * 100} table = Table(data) - view = table.view( - aggregates={"a": "stddev"}, - group_by=["b"] - ) + view = table.view(aggregates={"a": "stddev"}, group_by=["b"]) result = view.to_columns() assert result["a"] == approx([np.std(data["a"]), np.std(data["a"])]) @@ -1146,69 +808,44 @@ def test_view_sort_hidden(self): assert view.to_records() == [{"b": 4}, {"b": 2}] def test_view_sort_avg_nan(self): - data = { - "w": [3.5, 4.5, None, None, None, None, 1.5, 2.5], - "x": [1, 2, 3, 4, 4, 3, 2, 1], - "y": ["a", "b", "c", "d", "e", "f", "g", "h"] - } + data = {"w": [3.5, 4.5, None, None, None, None, 1.5, 2.5], "x": [1, 2, 3, 4, 4, 3, 2, 1], "y": ["a", "b", "c", "d", "e", "f", "g", "h"]} tbl = Table(data) view = tbl.view( columns=["x", "w"], group_by=["y"], sort=[["w", "asc"]], - aggregates={ - "w": "avg", - "x": "unique" - }, + aggregates={"w": "avg", "x": "unique"}, ) assert view.to_dict() == { "__ROW_PATH__": [[], ["c"], ["d"], ["e"], ["f"], ["g"], ["h"], ["a"], ["b"]], "w": [3, None, None, None, None, 1.5, 2.5, 3.5, 4.5], - "x": [None, 3, 4, 4, 3, 2, 1, 1, 2] + "x": [None, 3, 4, 4, 3, 2, 1, 1, 2], } def test_view_sort_sum_nan(self): - data = { - "w": [3.5, 4.5, None, None, None, None, 1.5, 2.5], - "x": [1, 2, 3, 4, 4, 3, 2, 1], - "y": ["a", "b", "c", "d", "e", "f", "g", "h"] - } + data = {"w": [3.5, 4.5, None, None, None, None, 1.5, 2.5], "x": [1, 2, 3, 4, 4, 3, 2, 1], "y": ["a", "b", "c", "d", "e", "f", "g", "h"]} tbl = Table(data) view = tbl.view( columns=["x", "w"], group_by=["y"], sort=[["w", "asc"]], - aggregates={ - "w": "sum", - "x": "unique" - }, + aggregates={"w": "sum", "x": "unique"}, ) - assert view.to_dict() == { - "__ROW_PATH__": [[], ["c"], ["d"], ["e"], ["f"], ["g"], ["h"], ["a"], ["b"]], - "w": [12, 0, 0, 0, 0, 1.5, 2.5, 3.5, 4.5], - "x": [None, 3, 4, 4, 3, 2, 1, 1, 2] - } + assert view.to_dict() == {"__ROW_PATH__": [[], ["c"], ["d"], ["e"], ["f"], ["g"], ["h"], ["a"], ["b"]], "w": [12, 0, 0, 0, 0, 1.5, 2.5, 3.5, 4.5], "x": [None, 3, 4, 4, 3, 2, 1, 1, 2]} def test_view_sort_unique_nan(self): - data = { - "w": [3.5, 4.5, None, None, None, None, 1.5, 2.5], - "x": [1, 2, 3, 4, 4, 3, 2, 1], - "y": ["a", "b", "c", "d", "e", "f", "g", "h"] - } + data = {"w": [3.5, 4.5, None, None, None, None, 1.5, 2.5], "x": [1, 2, 3, 4, 4, 3, 2, 1], "y": ["a", "b", "c", "d", "e", "f", "g", "h"]} tbl = Table(data) view = tbl.view( columns=["x", "w"], group_by=["y"], sort=[["w", "asc"]], - aggregates={ - "w": "unique", - "x": "unique" - }, + aggregates={"w": "unique", "x": "unique"}, ) assert view.to_dict() == { "__ROW_PATH__": [[], ["c"], ["d"], ["e"], ["f"], ["g"], ["h"], ["a"], ["b"]], "w": [None, None, None, None, None, 1.5, 2.5, 3.5, 4.5], - "x": [None, 3, 4, 4, 3, 2, 1, 1, 2] + "x": [None, 3, 4, 4, 3, 2, 1, 1, 2], } # filter @@ -1497,10 +1134,7 @@ def cb2(port_id): def test_view_row_delta_zero(self, util): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] - update_data = { - "a": [5], - "b": [6] - } + update_data = {"a": [5], "b": [6]} def cb1(port_id, delta): compare_delta(delta, update_data) @@ -1512,15 +1146,10 @@ def cb1(port_id, delta): def test_view_row_delta_zero_column_subset(self, util): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] - update_data = { - "a": [5], - "b": [6] - } + update_data = {"a": [5], "b": [6]} def cb1(port_id, delta): - compare_delta(delta, { - "b": [6] - }) + compare_delta(delta, {"b": [6]}) tbl = Table(data) view = tbl.view(columns=["b"]) @@ -1528,78 +1157,46 @@ def cb1(port_id, delta): tbl.update(update_data) def test_view_row_delta_zero_from_schema(self, util): - update_data = { - "a": [5], - "b": [6] - } + update_data = {"a": [5], "b": [6]} def cb1(port_id, delta): compare_delta(delta, update_data) - tbl = Table({ - "a": int, - "b": int - }) + tbl = Table({"a": int, "b": int}) view = tbl.view() view.on_update(cb1, mode="row") tbl.update(update_data) def test_view_row_delta_zero_from_schema_column_subset(self, util): - update_data = { - "a": [5], - "b": [6] - } + update_data = {"a": [5], "b": [6]} - def cb1(port_id, delta): - compare_delta(delta, { - "b": [6] - }) + def cb1(port_id, delta): + compare_delta(delta, {"b": [6]}) - tbl = Table({ - "a": int, - "b": int - }) + tbl = Table({"a": int, "b": int}) view = tbl.view(columns=["b"]) view.on_update(cb1, mode="row") tbl.update(update_data) def test_view_row_delta_zero_from_schema_filtered(self, util): - update_data = { - "a": [8, 9, 10, 11], - "b": [1, 2, 3, 4] - } + update_data = {"a": [8, 9, 10, 11], "b": [1, 2, 3, 4]} def cb1(port_id, delta): - compare_delta(delta, { - "a": [11], - "b": [4] - }) - - tbl = Table({ - "a": int, - "b": int - }) + compare_delta(delta, {"a": [11], "b": [4]}) + + tbl = Table({"a": int, "b": int}) view = tbl.view(filter=[["a", ">", 10]]) view.on_update(cb1, mode="row") tbl.update(update_data) def test_view_row_delta_zero_from_schema_indexed(self, util): - update_data = { - "a": ["a", "b", "a"], - "b": [1, 2, 3] - } + update_data = {"a": ["a", "b", "a"], "b": [1, 2, 3]} def cb1(port_id, delta): - compare_delta(delta, { - "a": ["a", "b"], - "b": [3, 2] - }) + compare_delta(delta, {"a": ["a", "b"], "b": [3, 2]}) - tbl = Table({ - "a": str, - "b": int - }, index="a") + tbl = Table({"a": str, "b": int}, index="a") view = tbl.view() view.on_update(cb1, mode="row") @@ -1607,147 +1204,80 @@ def cb1(port_id, delta): tbl.update(update_data) def test_view_row_delta_zero_from_schema_indexed_filtered(self, util): - update_data = { - "a": [8, 9, 10, 11, 11], - "b": [1, 2, 3, 4, 5] - } + update_data = {"a": [8, 9, 10, 11, 11], "b": [1, 2, 3, 4, 5]} def cb1(port_id, delta): - compare_delta(delta, { - "a": [11], - "b": [5] - }) - - tbl = Table({ - "a": int, - "b": int - }, index="a") + compare_delta(delta, {"a": [11], "b": [5]}) + + tbl = Table({"a": int, "b": int}, index="a") view = tbl.view(filter=[["a", ">", 10]]) view.on_update(cb1, mode="row") tbl.update(update_data) def test_view_row_delta_one(self, util): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] - update_data = { - "a": [5], - "b": [6] - } + update_data = {"a": [5], "b": [6]} def cb1(port_id, delta): - compare_delta(delta, { - "a": [9, 5], - "b": [12, 6] - }) + compare_delta(delta, {"a": [9, 5], "b": [12, 6]}) tbl = Table(data) view = tbl.view(group_by=["a"]) - assert view.to_dict() == { - "__ROW_PATH__": [[], [1], [3]], - "a": [4, 1, 3], - "b": [6, 2, 4] - } + assert view.to_dict() == {"__ROW_PATH__": [[], [1], [3]], "a": [4, 1, 3], "b": [6, 2, 4]} view.on_update(cb1, mode="row") tbl.update(update_data) def test_view_row_delta_one_from_schema(self, util): - update_data = { - "a": [1, 2, 3, 4, 5], - "b": [6, 7, 8, 9, 10] - } + update_data = {"a": [1, 2, 3, 4, 5], "b": [6, 7, 8, 9, 10]} def cb1(port_id, delta): - compare_delta(delta, { - "a": [15, 1, 2, 3, 4, 5], - "b": [40, 6, 7, 8, 9, 10] - }) - - tbl = Table({ - "a": int, - "b": int - }) + compare_delta(delta, {"a": [15, 1, 2, 3, 4, 5], "b": [40, 6, 7, 8, 9, 10]}) + + tbl = Table({"a": int, "b": int}) view = tbl.view(group_by=["a"]) view.on_update(cb1, mode="row") tbl.update(update_data) def test_view_row_delta_one_from_schema_sorted(self, util): - update_data = { - "a": [1, 2, 3, 4, 5], - "b": [6, 7, 8, 9, 10] - } + update_data = {"a": [1, 2, 3, 4, 5], "b": [6, 7, 8, 9, 10]} def cb1(port_id, delta): - compare_delta(delta, { - "a": [15, 5, 4, 3, 2, 1], - "b": [40, 10, 9, 8, 7, 6] - }) - - tbl = Table({ - "a": int, - "b": int - }) + compare_delta(delta, {"a": [15, 5, 4, 3, 2, 1], "b": [40, 10, 9, 8, 7, 6]}) + + tbl = Table({"a": int, "b": int}) view = tbl.view(group_by=["a"], sort=[["a", "desc"]]) view.on_update(cb1, mode="row") tbl.update(update_data) def test_view_row_delta_one_from_schema_filtered(self, util): - update_data = { - "a": [1, 2, 3, 4, 5], - "b": [6, 7, 8, 9, 10] - } + update_data = {"a": [1, 2, 3, 4, 5], "b": [6, 7, 8, 9, 10]} def cb1(port_id, delta): - compare_delta(delta, { - "a": [9, 4, 5], - "b": [19, 9, 10] - }) - - tbl = Table({ - "a": int, - "b": int - }) + compare_delta(delta, {"a": [9, 4, 5], "b": [19, 9, 10]}) + + tbl = Table({"a": int, "b": int}) view = tbl.view(group_by=["a"], filter=[["a", ">", 3]]) view.on_update(cb1, mode="row") tbl.update(update_data) def test_view_row_delta_one_from_schema_sorted_filtered(self, util): - update_data = { - "a": [1, 2, 3, 4, 5], - "b": [6, 7, 8, 9, 10] - } + update_data = {"a": [1, 2, 3, 4, 5], "b": [6, 7, 8, 9, 10]} def cb1(port_id, delta): - compare_delta(delta, { - "a": [9, 5, 4], - "b": [19, 10, 9] - }) - - tbl = Table({ - "a": int, - "b": int - }) - view = tbl.view( - group_by=["a"], - sort=[["a", "desc"]], - filter=[["a", ">", 3]]) + compare_delta(delta, {"a": [9, 5, 4], "b": [19, 10, 9]}) + + tbl = Table({"a": int, "b": int}) + view = tbl.view(group_by=["a"], sort=[["a", "desc"]], filter=[["a", ">", 3]]) view.on_update(cb1, mode="row") tbl.update(update_data) def test_view_row_delta_one_from_schema_indexed(self, util): - update_data = { - "a": [1, 2, 3, 4, 5, 5, 4], - "b": [6, 7, 8, 9, 10, 11, 12] - } + update_data = {"a": [1, 2, 3, 4, 5, 5, 4], "b": [6, 7, 8, 9, 10, 11, 12]} def cb1(port_id, delta): - compare_delta(delta, { - "a": [15, 1, 2, 3, 4, 5], - "b": [44, 6, 7, 8, 12, 11] - }) + compare_delta(delta, {"a": [15, 1, 2, 3, 4, 5], "b": [44, 6, 7, 8, 12, 11]}) - tbl = Table({ - "a": int, - "b": int - }, index="a") + tbl = Table({"a": int, "b": int}, index="a") view = tbl.view(group_by=["a"]) view.on_update(cb1, mode="row") @@ -1755,21 +1285,12 @@ def cb1(port_id, delta): tbl.update(update_data) def test_view_row_delta_one_from_schema_sorted_indexed(self, util): - update_data = { - "a": [1, 2, 3, 4, 5, 5, 4], - "b": [6, 7, 8, 9, 10, 11, 12] - } + update_data = {"a": [1, 2, 3, 4, 5, 5, 4], "b": [6, 7, 8, 9, 10, 11, 12]} def cb1(port_id, delta): - compare_delta(delta, { - "a": [15, 4, 5, 3, 2, 1], - "b": [44, 12, 11, 8, 7, 6] - }) + compare_delta(delta, {"a": [15, 4, 5, 3, 2, 1], "b": [44, 12, 11, 8, 7, 6]}) - tbl = Table({ - "a": int, - "b": int - }, index="a") + tbl = Table({"a": int, "b": int}, index="a") view = tbl.view(group_by=["a"], sort=[["b", "desc"]]) view.on_update(cb1, mode="row") @@ -1777,21 +1298,12 @@ def cb1(port_id, delta): tbl.update(update_data) def test_view_row_delta_one_from_schema_filtered_indexed(self, util): - update_data = { - "a": [1, 2, 3, 4, 5, 5, 4], - "b": [6, 7, 8, 9, 10, 11, 12] - } + update_data = {"a": [1, 2, 3, 4, 5, 5, 4], "b": [6, 7, 8, 9, 10, 11, 12]} def cb1(port_id, delta): - compare_delta(delta, { - "a": [9, 4, 5], - "b": [23, 12, 11] - }) + compare_delta(delta, {"a": [9, 4, 5], "b": [23, 12, 11]}) - tbl = Table({ - "a": int, - "b": int - }, index="a") + tbl = Table({"a": int, "b": int}, index="a") view = tbl.view(group_by=["a"], filter=[["a", ">", 3]]) view.on_update(cb1, mode="row") @@ -1800,20 +1312,10 @@ def cb1(port_id, delta): def test_view_row_delta_two(self, util): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] - update_data = { - "a": [5], - "b": [6] - } + update_data = {"a": [5], "b": [6]} def cb1(port_id, delta): - compare_delta(delta, { - "2|a": [1, None], - "2|b": [2, None], - "4|a": [3, None], - "4|b": [4, None], - "6|a": [5, 5], - "6|b": [6, 6] - }) + compare_delta(delta, {"2|a": [1, None], "2|b": [2, None], "4|a": [3, None], "4|b": [4, None], "6|a": [5, 5], "6|b": [6, 6]}) tbl = Table(data) view = tbl.view(group_by=["a"], split_by=["b"]) @@ -1831,17 +1333,9 @@ def test_view_row_delta_two_from_schema(self, util): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] def cb1(port_id, delta): - compare_delta(delta, { - "2|a": [1, 1, None], - "2|b": [2, 2, None], - "4|a": [3, None, 3], - "4|b": [4, None, 4] - }) - - tbl = Table({ - "a": int, - "b": int - }) + compare_delta(delta, {"2|a": [1, 1, None], "2|b": [2, 2, None], "4|a": [3, None, 3], "4|b": [4, None, 4]}) + + tbl = Table({"a": int, "b": int}) view = tbl.view(group_by=["a"], split_by=["b"]) view.on_update(cb1, mode="row") tbl.update(data) @@ -1850,37 +1344,19 @@ def test_view_row_delta_two_from_schema_indexed(self, util): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 3, "b": 5}] def cb1(port_id, delta): - compare_delta(delta, { - "2|a": [1, 1, None], - "2|b": [2, 2, None], - "5|a": [3, None, 3], - "5|b": [5, None, 5] - }) - - tbl = Table({ - "a": int, - "b": int - }, index="a") + compare_delta(delta, {"2|a": [1, 1, None], "2|b": [2, 2, None], "5|a": [3, None, 3], "5|b": [5, None, 5]}) + + tbl = Table({"a": int, "b": int}, index="a") view = tbl.view(group_by=["a"], split_by=["b"]) view.on_update(cb1, mode="row") tbl.update(data) def test_view_row_delta_two_column_only(self, util): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] - update_data = { - "a": [5], - "b": [6] - } + update_data = {"a": [5], "b": [6]} def cb1(port_id, delta): - compare_delta(delta, { - "2|a": [1, None], - "2|b": [2, None], - "4|a": [3, None], - "4|b": [4, None], - "6|a": [5, 5], - "6|b": [6, 6] - }) + compare_delta(delta, {"2|a": [1, None], "2|b": [2, None], "4|a": [3, None], "4|b": [4, None], "6|a": [5, 5], "6|b": [6, 6]}) tbl = Table(data) view = tbl.view(split_by=["b"]) @@ -1895,20 +1371,10 @@ def cb1(port_id, delta): def test_view_row_delta_two_column_only_indexed(self, util): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 3, "b": 5}] - update_data = { - "a": [5], - "b": [6] - } + update_data = {"a": [5], "b": [6]} def cb1(port_id, delta): - compare_delta(delta, { - "2|a": [1, None], - "2|b": [2, None], - "5|a": [3, None], - "5|b": [5, None], - "6|a": [5, 5], - "6|b": [6, 6] - }) + compare_delta(delta, {"2|a": [1, None], "2|b": [2, None], "5|a": [3, None], "5|b": [5, None], "6|a": [5, 5], "6|b": [6, 6]}) tbl = Table(data, index="a") view = tbl.view(split_by=["b"]) @@ -1925,17 +1391,9 @@ def test_view_row_delta_two_column_only_from_schema(self, util): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}] def cb1(port_id, delta): - compare_delta(delta, { - "2|a": [1, 1, None], - "2|b": [2, 2, None], - "4|a": [3, None, 3], - "4|b": [4, None, 4] - }) - - tbl = Table({ - "a": int, - "b": int - }) + compare_delta(delta, {"2|a": [1, 1, None], "2|b": [2, 2, None], "4|a": [3, None, 3], "4|b": [4, None, 4]}) + + tbl = Table({"a": int, "b": int}) view = tbl.view(split_by=["b"]) view.on_update(cb1, mode="row") tbl.update(data) @@ -1944,17 +1402,9 @@ def test_view_row_delta_two_column_only_from_schema_indexed(self, util): data = [{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 3, "b": 5}] def cb1(port_id, delta): - compare_delta(delta, { - "2|a": [1, 1, None], - "2|b": [2, 2, None], - "5|a": [3, None, 3], - "5|b": [5, None, 5] - }) - - tbl = Table({ - "a": int, - "b": int - }, index="a") + compare_delta(delta, {"2|a": [1, 1, None], "2|b": [2, 2, None], "5|a": [3, None, 3], "5|b": [5, None, 5]}) + + tbl = Table({"a": int, "b": int}, index="a") view = tbl.view(split_by=["b"]) view.on_update(cb1, mode="row") tbl.update(data) @@ -1990,10 +1440,10 @@ def test_view_context_two_update_clears_column_regression(self, util): ) assert view.to_records() == [ - {'__ROW_PATH__': [], 'a|c': 7.5, 'b|c': 16.5}, - {'__ROW_PATH__': [1], 'a|c': 1.5, 'b|c': 4.5}, - {'__ROW_PATH__': [2], 'a|c': 2.5, 'b|c': 5.5}, - {'__ROW_PATH__': [3], 'a|c': 3.5, 'b|c': 6.5} + {"__ROW_PATH__": [], "a|c": 7.5, "b|c": 16.5}, + {"__ROW_PATH__": [1], "a|c": 1.5, "b|c": 4.5}, + {"__ROW_PATH__": [2], "a|c": 2.5, "b|c": 5.5}, + {"__ROW_PATH__": [3], "a|c": 3.5, "b|c": 6.5}, ] tbl.update( @@ -2020,10 +1470,10 @@ def test_view_context_two_update_clears_column_regression(self, util): ) assert view.to_records() == [ - {'__ROW_PATH__': [], 'a|c': 7.5, 'b|c': 16.5}, - {'__ROW_PATH__': [1], 'a|c': 1.5, 'b|c': 4.5}, - {'__ROW_PATH__': [2], 'a|c': 2.5, 'b|c': 5.5}, - {'__ROW_PATH__': [3], 'a|c': 3.5, 'b|c': 6.5} + {"__ROW_PATH__": [], "a|c": 7.5, "b|c": 16.5}, + {"__ROW_PATH__": [1], "a|c": 1.5, "b|c": 4.5}, + {"__ROW_PATH__": [2], "a|c": 2.5, "b|c": 5.5}, + {"__ROW_PATH__": [3], "a|c": 3.5, "b|c": 6.5}, ] assert tbl.size() == 9 @@ -2159,39 +1609,19 @@ def test_invalid_columns_not_in_expression_should_throw(self): data = [{"a": 1, "b": 2, "c": "a"}, {"a": 3, "b": 4, "c": "b"}] tbl = Table(data) with raises(PerspectiveCppError) as ex: - tbl.view( - columns=["abc", "x"], - expressions=['// abc \n 1 + 2'] - ) + tbl.view(columns=["abc", "x"], expressions=["// abc \n 1 + 2"]) assert str(ex.value) == "Invalid column 'x' found in View columns.\n" def test_should_not_throw_valid_expression(self): data = [{"a": 1, "b": 2, "c": "a"}, {"a": 3, "b": 4, "c": "b"}] tbl = Table(data) - view = tbl.view( - columns=["abc"], - expressions=["// abc \n 'hello!'"] - ) + view = tbl.view(columns=["abc"], expressions=["// abc \n 'hello!'"]) - assert view.schema() == { - "abc": str - } + assert view.schema() == {"abc": str} def test_should_not_throw_valid_expression_config(self): data = [{"a": 1, "b": 2, "c": "a"}, {"a": 3, "b": 4, "c": "b"}] tbl = Table(data) - view = tbl.view( - aggregates={ - "abc": "dominant" - }, - columns=["abc"], - sort=[["abc", "desc"]], - filter=[["abc", "==", "A"]], - group_by=["abc"], - split_by=["abc"], - expressions=["// abc \n 'hello!'"] - ) + view = tbl.view(aggregates={"abc": "dominant"}, columns=["abc"], sort=[["abc", "desc"]], filter=[["abc", "==", "A"]], group_by=["abc"], split_by=["abc"], expressions=["// abc \n 'hello!'"]) - assert view.schema() == { - "abc": str - } + assert view.schema() == {"abc": str} diff --git a/python/perspective/perspective/tests/table/test_view_expression.py b/python/perspective/perspective/tests/table/test_view_expression.py index 95e9cca14f..bdeb0deb15 100644 --- a/python/perspective/perspective/tests/table/test_view_expression.py +++ b/python/perspective/perspective/tests/table/test_view_expression.py @@ -19,9 +19,11 @@ from perspective import Table, PerspectiveCppError from .test_view import compare_delta + def randstr(length, input=ascii_letters): return "".join(choices(input, k=length)) + class TestViewExpression(object): def test_table_validate_expressions_empty(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) @@ -111,11 +113,11 @@ def test_view_expression_schema_all_types(self): "b": [5, 6, 7, 8], '"a"': [1, 2, 3, 4], '"b" * 0.5': [2.5, 3, 3.5, 4], - "'abcdefg'": ['abcdefg' for _ in range(4)], + "'abcdefg'": ["abcdefg" for _ in range(4)], "true and false": [False for _ in range(4)], 'float("a") > 2 ? null : 1': [1, 1, None, None], "today()": [today for _ in range(4)], - "length('abcd')": [4 for _ in range(4)] + "length('abcd')": [4 for _ in range(4)], } validated = table.validate_expressions(expressions) @@ -165,11 +167,7 @@ def test_view_expression_create(self): def test_view_expression_string_per_page(self): table = Table({"a": [i for i in range(100)]}) big_strings = [randstr(6400) for _ in range(4)] - view = table.view( - expressions=[ - "//computed{}\nvar x := '{}'; lower(x)".format(i, big_strings[i]) for i in range(4) - ] - ) + view = table.view(expressions=["//computed{}\nvar x := '{}'; lower(x)".format(i, big_strings[i]) for i in range(4)]) result = view.to_columns() schema = view.expression_schema() @@ -189,11 +187,7 @@ def test_view_expression_string_page_stress(self): "".join(["d" for _ in range(640)]), ] - view = table.view( - expressions=[ - "//computed\nvar a := '{}'; var b := '{}'; var c := '{}'; var d := '{}'; concat(a, b, c, d)".format(*big_strings) - ] - ) + view = table.view(expressions=["//computed\nvar a := '{}'; var b := '{}'; var c := '{}'; var d := '{}'; concat(a, b, c, d)".format(*big_strings)]) result = view.to_columns() schema = view.expression_schema() @@ -225,19 +219,13 @@ def make_expression(idx): expr.append("var {} := {};".format(name, string_literal)) - expr.append("concat(\"a\", {})".format(", ".join(concat_cols))) + expr.append('concat("a", {})'.format(", ".join(concat_cols))) - return { - "expression_name": expr[0][2:], - "expression": "\n".join(expr), - "output": "".join(concat_result) - } + return {"expression_name": expr[0][2:], "expression": "\n".join(expr), "output": "".join(concat_result)} expressions = [make_expression(i) for i in range(10)] - view = table.view( - expressions=[expr["expression"] for expr in expressions] - ) + view = table.view(expressions=[expr["expression"] for expr in expressions]) result = view.to_columns() schema = view.expression_schema() @@ -266,10 +254,7 @@ def test_view_expression_collide_local_var(self): result = view.to_columns() schema = view.expression_schema() - assert schema == { - "computed": str, - "computed2": str - } + assert schema == {"computed": str, "computed2": str} assert result["computed"] == ["".join(strings[:4]) for _ in range(4)] assert result["computed2"] == ["".join(strings[4:]) for _ in range(4)] @@ -294,11 +279,7 @@ def make_expression(): output_str = string_literal expression.append(output_var_name) - return { - "expression_name": expression_name, - "expression": "".join(expression), - "output": output_str - } + return {"expression_name": expression_name, "expression": "".join(expression), "output": output_str} table = Table({"a": [1, 2, 3, 4]}) @@ -315,13 +296,11 @@ def make_expression(): def test_view_expression_string_literal_compare(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) - validated = table.validate_expressions(['// computed \n \'a\' == \'a\'']) + validated = table.validate_expressions(["// computed \n 'a' == 'a'"]) - assert validated["expression_schema"] == { - "computed": "boolean" - } + assert validated["expression_schema"] == {"computed": "boolean"} - view = table.view(expressions=['// computed \n \'a\' == \'a\'']) + view = table.view(expressions=["// computed \n 'a' == 'a'"]) assert view.to_columns() == { "a": [1, 2, 3, 4], @@ -333,13 +312,11 @@ def test_view_expression_string_literal_compare(self): def test_view_expression_string_literal_compare_null(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) - validated = table.validate_expressions(['// computed \n \'a\' == null']) + validated = table.validate_expressions(["// computed \n 'a' == null"]) - assert validated["expression_schema"] == { - "computed": "float" - } + assert validated["expression_schema"] == {"computed": "float"} - view = table.view(expressions=['// computed \n \'a\' == null']) + view = table.view(expressions=["// computed \n 'a' == null"]) assert view.to_columns() == { "a": [1, 2, 3, 4], @@ -351,13 +328,11 @@ def test_view_expression_string_literal_compare_null(self): def test_view_expression_string_literal_compare_column(self): table = Table({"a": ["a", "a", "b", "c"]}) - validated = table.validate_expressions(['// computed \n "a" == \'a\'']) + validated = table.validate_expressions(["// computed \n \"a\" == 'a'"]) - assert validated["expression_schema"] == { - "computed": "boolean" - } + assert validated["expression_schema"] == {"computed": "boolean"} - view = table.view(expressions=['// computed \n "a" == \'a\'']) + view = table.view(expressions=["// computed \n \"a\" == 'a'"]) assert view.to_columns() == { "a": ["a", "a", "b", "c"], @@ -368,13 +343,11 @@ def test_view_expression_string_literal_compare_column(self): def test_view_expression_string_literal_compare_column_null(self): table = Table({"a": ["a", None, "b", "c", None]}) - validated = table.validate_expressions(['// computed \n "a" == \'a\'']) + validated = table.validate_expressions(["// computed \n \"a\" == 'a'"]) - assert validated["expression_schema"] == { - "computed": "boolean" - } + assert validated["expression_schema"] == {"computed": "boolean"} - view = table.view(expressions=['// computed \n "a" == \'a\'']) + view = table.view(expressions=["// computed \n \"a\" == 'a'"]) assert view.to_columns() == { "a": ["a", None, "b", "c", None], @@ -385,13 +358,11 @@ def test_view_expression_string_literal_compare_column_null(self): def test_view_expression_string_literal_compare_column_null_long(self): table = Table({"a": ["abcdefghijklmnopqrstuvwxyz", None, "abcdefghijklmnopqrstuvwxyz", "aabcdefghijklmnopqrstuvwxyz", None]}) - validated = table.validate_expressions(['// computed \n "a" == \'abcdefghijklmnopqrstuvwxyz\'']) + validated = table.validate_expressions(["// computed \n \"a\" == 'abcdefghijklmnopqrstuvwxyz'"]) - assert validated["expression_schema"] == { - "computed": "boolean" - } + assert validated["expression_schema"] == {"computed": "boolean"} - view = table.view(expressions=['// computed \n "a" == \'abcdefghijklmnopqrstuvwxyz\'']) + view = table.view(expressions=["// computed \n \"a\" == 'abcdefghijklmnopqrstuvwxyz'"]) result = view.to_columns() assert result["computed"] == [True, False, True, False, False] @@ -399,26 +370,22 @@ def test_view_expression_string_literal_compare_column_null_long(self): def test_view_expression_string_literal_compare_column_null_long_var(self): table = Table({"a": ["abcdefghijklmnopqrstuvwxyz", None, "abcdefghijklmnopqrstuvwxyz", "aabcdefghijklmnopqrstuvwxyz", None]}) - validated = table.validate_expressions(['// computed \n var xyz := \'abcdefghijklmnopqrstuvwxyz\'; "a" == xyz']) + validated = table.validate_expressions(["// computed \n var xyz := 'abcdefghijklmnopqrstuvwxyz'; \"a\" == xyz"]) - assert validated["expression_schema"] == { - "computed": "boolean" - } + assert validated["expression_schema"] == {"computed": "boolean"} - view = table.view(expressions=['// computed \n var xyz := \'abcdefghijklmnopqrstuvwxyz\'; "a" == xyz']) + view = table.view(expressions=["// computed \n var xyz := 'abcdefghijklmnopqrstuvwxyz'; \"a\" == xyz"]) result = view.to_columns() assert result["computed"] == [True, False, True, False, False] assert view.expression_schema() == {"computed": bool} def test_view_expression_string_literal_compare_if(self): table = Table({"a": ["a", "a", "b", "c"]}) - validated = table.validate_expressions(['// computed \n if("a" == \'a\', 1, 2)']) + validated = table.validate_expressions(["// computed \n if(\"a\" == 'a', 1, 2)"]) - assert validated["expression_schema"] == { - "computed": "float" - } + assert validated["expression_schema"] == {"computed": "float"} - view = table.view(expressions=['// computed \n if("a" == \'a\', 1, 2)']) + view = table.view(expressions=["// computed \n if(\"a\" == 'a', 1, 2)"]) assert view.to_columns() == { "a": ["a", "a", "b", "c"], @@ -434,7 +401,7 @@ def test_view_expression_string_literal_var(self): view = table.view(expressions=["var x := 'Eabcdefghijklmn'; var y := '0123456789'; concat(x, y)"]) assert view.to_columns() == { "a": [1, 2, 3], - "var x := 'Eabcdefghijklmn'; var y := '0123456789'; concat(x, y)": ["Eabcdefghijklmn0123456789", "Eabcdefghijklmn0123456789", "Eabcdefghijklmn0123456789"] + "var x := 'Eabcdefghijklmn'; var y := '0123456789'; concat(x, y)": ["Eabcdefghijklmn0123456789", "Eabcdefghijklmn0123456789", "Eabcdefghijklmn0123456789"], } def test_view_streaming_expression(self): @@ -446,7 +413,7 @@ def data(): for _ in range(5): table.update(data()) - + assert table.size() == 300 result = view.to_dict() assert result["123"] == [123 for _ in range(300)] @@ -460,7 +427,7 @@ def data(): for _ in range(5): table.update(data()) - + assert table.size() == 50 result = view.to_dict() assert result["123"] == [123 for _ in range(50)] @@ -474,11 +441,9 @@ def data(): for _ in range(5): table.update(data()) - + assert table.size() == 300 - assert view.expression_schema() == { - "c0": float - } + assert view.expression_schema() == {"c0": float} def test_view_streaming_expression_two(self): def data(): @@ -489,12 +454,9 @@ def data(): for i in range(5): table.update(data()) - + assert table.size() == 300 - assert view.expression_schema() == { - "c0": float, - "c1": int # pivoted - } + assert view.expression_schema() == {"c0": float, "c1": int} # pivoted def test_view_expression_create_no_alias(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) @@ -510,10 +472,7 @@ def test_view_expression_should_not_overwrite_real(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) with raises(PerspectiveCppError) as ex: table.view(expressions=['// a \n upper("a")']) - assert ( - str(ex.value) - == "View creation failed: cannot create expression column 'a' that overwrites a column that already exists.\n" - ) + assert str(ex.value) == "View creation failed: cannot create expression column 'a' that overwrites a column that already exists.\n" def test_view_expression_should_resolve_to_last_alias(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) @@ -556,17 +515,11 @@ def test_view_expression_multiple_views_with_the_same_alias_should_not_overwrite ): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) - view = table.view( - expressions=['// computed \n "a" + "b"'] - ) + view = table.view(expressions=['// computed \n "a" + "b"']) - view2 = table.view( - expressions=['// computed \n "a" * "b"'] - ) + view2 = table.view(expressions=['// computed \n "a" * "b"']) - assert view.expression_schema() == { - "computed": float - } + assert view.expression_schema() == {"computed": float} assert view2.expression_schema() == { "computed": float, @@ -580,25 +533,11 @@ def test_view_expression_multiple_views_with_the_same_alias_pivoted( ): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) - view = table.view( - group_by=["computed"], - aggregates={ - "computed": ["weighted mean", "b"] - }, - expressions=['// computed \n "a" + "b"'] - ) + view = table.view(group_by=["computed"], aggregates={"computed": ["weighted mean", "b"]}, expressions=['// computed \n "a" + "b"']) - view2 = table.view( - group_by=["computed"], - aggregates={ - "computed": "last" - }, - expressions=['// computed \nconcat(\'abc\', \' \', \'def\')'] - ) + view2 = table.view(group_by=["computed"], aggregates={"computed": "last"}, expressions=["// computed \nconcat('abc', ' ', 'def')"]) - assert view.expression_schema() == { - "computed": float - } + assert view.expression_schema() == {"computed": float} assert view2.expression_schema() == { "computed": str, @@ -613,7 +552,6 @@ def test_view_expression_multiple_views_with_the_same_alias_pivoted( assert result["computed"] == [9.384615384615385, 6, 8, 10, 12] assert result2["computed"] == ["abc def", "abc def"] - def test_view_expression_multiple_views_with_the_same_alias_all_types( self, ): @@ -623,21 +561,16 @@ def test_view_expression_multiple_views_with_the_same_alias_all_types( month_bucketed = datetime(today.year, today.month, 1) minute_bucketed = datetime(now.year, now.month, now.day, now.hour, now.minute, 0, 0) - table = Table({ - "a": [1, 2, 3, 4], - "b": [5.5, 6.5, 7.5, 8.5], - "c": [datetime.now() for _ in range(4)], - "d": [date.today() for _ in range(4)], - "e": [True, False, True, False], - "f": ["a", "b", "c", "d"] - }) + table = Table( + {"a": [1, 2, 3, 4], "b": [5.5, 6.5, 7.5, 8.5], "c": [datetime.now() for _ in range(4)], "d": [date.today() for _ in range(4)], "e": [True, False, True, False], "f": ["a", "b", "c", "d"]} + ) view = table.view( expressions=[ '// computed \n "a" + "b"', - '// computed2 \n bucket("c", \'M\')', - '// computed3 \n concat(\'a\', \'b\', \'c\')', - '// computed4 \n \'new string\'', + "// computed2 \n bucket(\"c\", 'M')", + "// computed3 \n concat('a', 'b', 'c')", + "// computed4 \n 'new string'", ] ) @@ -645,7 +578,7 @@ def test_view_expression_multiple_views_with_the_same_alias_all_types( expressions=[ '// computed \n upper("f")', '// computed2 \n 20 + ("b" * "a")', - '// computed4 \n bucket("c", \'m\')', + "// computed4 \n bucket(\"c\", 'm')", ] ) @@ -667,7 +600,7 @@ def test_view_expression_multiple_views_with_the_same_alias_all_types( assert result["computed"] == [6.5, 8.5, 10.5, 12.5] assert result2["computed"] == ["A", "B", "C", "D"] - + assert result["computed2"] == [month_bucketed for _ in range(4)] assert result2["computed2"] == [25.5, 33, 42.5, 54] @@ -679,12 +612,7 @@ def test_view_expression_multiple_views_with_the_same_alias_all_types( def test_view_expression_create_no_columns(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) - view = table.view( - columns=[], - expressions=[ - '// computed \n "a" + "b"' - ] - ) + view = table.view(columns=[], expressions=['// computed \n "a" + "b"']) assert view.to_columns() == {} assert view.schema() == {} @@ -693,12 +621,7 @@ def test_view_expression_create_no_columns(self): def test_view_expression_create_columns(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) - view = table.view( - columns=["computed"], - expressions=[ - '// computed \n "a" + "b"' - ] - ) + view = table.view(columns=["computed"], expressions=['// computed \n "a" + "b"']) assert view.to_columns() == {"computed": [6, 8, 10, 12]} assert view.schema() == {"computed": float} # computed column should still exist @@ -706,11 +629,7 @@ def test_view_expression_create_columns(self): def test_view_expression_create_clear(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) - view = table.view( - expressions=[ - '// computed \n "a" + "b"' - ] - ) + view = table.view(expressions=['// computed \n "a" + "b"']) assert view.to_columns() == { "a": [1, 2, 3, 4], "b": [5, 6, 7, 8], @@ -722,11 +641,7 @@ def test_view_expression_create_clear(self): def test_view_expression_create_replace(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) - view = table.view( - expressions=[ - '// computed \n "a" + "b"' - ] - ) + view = table.view(expressions=['// computed \n "a" + "b"']) assert view.to_columns() == { "a": [1, 2, 3, 4], "b": [5, 6, 7, 8], @@ -742,12 +657,7 @@ def test_view_expression_create_replace(self): def test_view_expression_multiple_dependents_replace(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) - view = table.view( - expressions=[ - '// computed \n "a" + "b"', - '// final \n ("a" + "b") ^ 2' - ] - ) + view = table.view(expressions=['// computed \n "a" + "b"', '// final \n ("a" + "b") ^ 2']) assert view.to_columns() == { "a": [1, 2, 3, 4], "b": [5, 6, 7, 8], @@ -777,11 +687,7 @@ def test_view_expression_multiple_views_should_not_conflate(self): ] ) - view2 = table.view( - expressions=[ - '// computed2 \n "a" - "b"' - ] - ) + view2 = table.view(expressions=['// computed2 \n "a" - "b"']) assert view.schema() == {"a": int, "b": int, "computed": float} @@ -808,11 +714,7 @@ def test_view_expression_multiple_views_should_all_clear(self): ] ) - view2 = table.view( - expressions=[ - '// computed2 \n "a" - "b"' - ] - ) + view2 = table.view(expressions=['// computed2 \n "a" - "b"']) assert view.schema() == {"a": int, "b": int, "computed": float} @@ -849,11 +751,7 @@ def test_view_expression_multiple_views_should_all_replace(self): ] ) - view2 = table.view( - expressions=[ - '// computed2 \n "a" - "b"' - ] - ) + view2 = table.view(expressions=['// computed2 \n "a" - "b"']) assert view.schema() == {"a": int, "b": int, "computed": float} @@ -903,11 +801,7 @@ def test_view_expression_delete_and_create(self): view.delete() - view2 = table.view( - expressions=[ - '// computed \n "a" - "b"' - ] - ) + view2 = table.view(expressions=['// computed \n "a" - "b"']) assert view2.schema() == {"a": int, "b": int, "computed": float} @@ -920,23 +814,13 @@ def test_view_expression_delete_and_create(self): def test_view_expression_delete_and_create_with_updates(self): table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) - view = table.view( - expressions=[ - '// computed \n "a" + "b"', - "upper(concat('abc', 'def'))" - ] - ) + view = table.view(expressions=['// computed \n "a" + "b"', "upper(concat('abc', 'def'))"]) assert view.schema() == {"a": int, "b": int, "computed": float, "upper(concat('abc', 'def'))": str} table.update({"a": [5, 6], "b": [9, 10]}) - assert view.to_columns() == { - "a": [1, 2, 3, 4, 5, 6], - "b": [5, 6, 7, 8, 9, 10], - "computed": [6, 8, 10, 12, 14, 16], - "upper(concat('abc', 'def'))": ["ABCDEF" for _ in range(6)] - } + assert view.to_columns() == {"a": [1, 2, 3, 4, 5, 6], "b": [5, 6, 7, 8, 9, 10], "computed": [6, 8, 10, 12, 14, 16], "upper(concat('abc', 'def'))": ["ABCDEF" for _ in range(6)]} view.delete() @@ -1002,7 +886,6 @@ def test_view_expression_delta_zero(self, util): def updater(port, delta): compare_delta(delta, {"a": [5, 6], "b": [9, 10]}) - table.update({"a": [5, 6], "b": [9, 10]}) assert view.to_columns() == { @@ -1010,6 +893,7 @@ def updater(port, delta): "b": [5, 6, 7, 8, 9, 10], "computed": [6, 8, 10, 12, 14, 16], } + def test_view_delete_with_scope(self): """Tests that `View`'s `__del__` method, when called by the Python reference counter, leaves an empty `Table` in a clean state. @@ -1041,7 +925,7 @@ def test_view_expression_with_custom_columns(self): columns=["computed", "b"], expressions=[ '// computed \n "a" + "b"', - ] + ], ) assert view.to_columns() == { "b": [5, 6, 7, 8], @@ -1054,7 +938,7 @@ def test_view_expression_with_group_by(self): group_by=["computed"], expressions=[ '// computed \n "a" + "b"', - ] + ], ) assert view.to_columns() == { "__ROW_PATH__": [[], [6], [8], [10], [12]], @@ -1070,7 +954,7 @@ def test_view_expression_with_group_by_clear(self): group_by=["computed"], expressions=[ '// computed \n "a" + "b"', - ] + ], ) assert view.to_columns() == { @@ -1096,7 +980,7 @@ def test_view_expression_with_group_by_replace(self): group_by=["computed"], expressions=[ '// computed \n "a" + "b"', - ] + ], ) assert view.to_columns() == { @@ -1121,7 +1005,7 @@ def test_view_expression_with_split_by(self): split_by=["computed"], expressions=[ '// computed \n "a" + "b"', - ] + ], ) assert view.to_columns() == { "6|a": [1, None, None, None], @@ -1144,7 +1028,7 @@ def test_view_expression_with_row_split_by(self): split_by=["computed"], expressions=[ '// computed \n "a" + "b"', - ] + ], ) assert view.to_columns() == { "6|a": [1, None, None, None], @@ -1163,10 +1047,7 @@ def test_view_expression_with_row_split_by(self): def test_view_expression_with_sort(self): table = Table({"a": ["a", "ab", "abc", "abcd"]}) - view = table.view( - sort=[["computed", "desc"]], - expressions=['// computed \n length("a")'] - ) + view = table.view(sort=[["computed", "desc"]], expressions=['// computed \n length("a")']) assert view.to_columns() == { "a": ["abcd", "abc", "ab", "a"], @@ -1175,18 +1056,13 @@ def test_view_expression_with_sort(self): def test_view_expression_with_filter(self): table = Table({"a": ["a", "ab", "abc", "abcd"]}) - view = table.view( - filter=[["computed", ">=", 3]], - expressions=['// computed \n length("a")'] - ) + view = table.view(filter=[["computed", ">=", 3]], expressions=['// computed \n length("a")']) assert view.to_columns() == {"a": ["abc", "abcd"], "computed": [3, 4]} def test_view_day_of_week_date(self): table = Table({"a": [date(2020, 3, i) for i in range(9, 14)]}) - view = table.view( - expressions=['// bucket \n day_of_week("a")'] - ) + view = table.view(expressions=['// bucket \n day_of_week("a")']) assert view.schema() == {"a": date, "bucket": str} assert view.to_columns() == { "a": [datetime(2020, 3, i) for i in range(9, 14)], @@ -1200,12 +1076,8 @@ def test_view_day_of_week_date(self): } def test_view_day_of_week_datetime(self): - table = Table( - {"a": [datetime(2020, 3, i, 12, 30) for i in range(9, 14)]} - ) - view = table.view( - expressions=['// bucket \n day_of_week("a")'] - ) + table = Table({"a": [datetime(2020, 3, i, 12, 30) for i in range(9, 14)]}) + view = table.view(expressions=['// bucket \n day_of_week("a")']) assert view.schema() == {"a": datetime, "bucket": str} assert view.to_columns() == { "a": [datetime(2020, 3, i, 12, 30) for i in range(9, 14)], @@ -1220,9 +1092,7 @@ def test_view_day_of_week_datetime(self): def test_view_month_of_year_date(self): table = Table({"a": [date(2020, i, 15) for i in range(1, 13)]}) - view = table.view( - expressions=['// bucket \n month_of_year("a")'] - ) + view = table.view(expressions=['// bucket \n month_of_year("a")']) assert view.schema() == {"a": date, "bucket": str} assert view.to_columns() == { "a": [datetime(2020, i, 15) for i in range(1, 13)], @@ -1248,9 +1118,7 @@ def test_view_month_of_year_datetime(self): "a": [datetime(2020, i, 15) for i in range(1, 13)], } ) - view = table.view( - expressions=['// bucket \n month_of_year("a")'] - ) + view = table.view(expressions=['// bucket \n month_of_year("a")']) assert view.schema() == {"a": datetime, "bucket": str} assert view.to_columns() == { "a": [datetime(2020, i, 15) for i in range(1, 13)], @@ -1282,9 +1150,7 @@ def test_view_day_bucket_date(self): ], } ) - view = table.view( - expressions=["// bucket \n bucket(\"a\", 'D')"] - ) + view = table.view(expressions=["// bucket \n bucket(\"a\", 'D')"]) assert view.schema() == {"a": date, "bucket": date} assert view.to_columns() == { "a": [ @@ -1312,9 +1178,7 @@ def test_view_day_bucket_date_with_null(self): ], } ) - view = table.view( - expressions=["// bucket \n bucket(\"a\", 'D')"] - ) + view = table.view(expressions=["// bucket \n bucket(\"a\", 'D')"]) assert view.schema() == {"a": date, "bucket": date} assert view.to_columns() == { "a": [ @@ -1342,9 +1206,7 @@ def test_view_day_bucket_datetime(self): ], } ) - view = table.view( - expressions=["// bucket \n bucket(\"a\", 'D')"] - ) + view = table.view(expressions=["// bucket \n bucket(\"a\", 'D')"]) assert view.schema() == {"a": datetime, "bucket": date} assert view.to_columns() == { "a": [ @@ -1372,9 +1234,7 @@ def test_view_month_bucket_date(self): ], } ) - view = table.view( - expressions=["// bucket \n bucket(\"a\", 'M')"] - ) + view = table.view(expressions=["// bucket \n bucket(\"a\", 'M')"]) assert view.schema() == {"a": date, "bucket": date} assert view.to_columns() == { "a": [ @@ -1402,9 +1262,7 @@ def test_view_month_bucket_date_with_null(self): ], } ) - view = table.view( - expressions=["// bucket \n bucket(\"a\", 'M')"] - ) + view = table.view(expressions=["// bucket \n bucket(\"a\", 'M')"]) assert view.schema() == {"a": date, "bucket": date} assert view.to_columns() == { "a": [ @@ -1432,9 +1290,7 @@ def test_view_month_bucket_datetime(self): ], } ) - view = table.view( - expressions=["// bucket \n bucket(\"a\", 'M')"] - ) + view = table.view(expressions=["// bucket \n bucket(\"a\", 'M')"]) assert view.schema() == {"a": datetime, "bucket": date} assert view.to_columns() == { "a": [ @@ -1457,9 +1313,7 @@ def test_view_month_bucket_datetime_with_null(self): "a": [datetime(2020, 1, 1), None, None, datetime(2020, 3, 15)], } ) - view = table.view( - expressions=["// bucket \n bucket(\"a\", 'M')"] - ) + view = table.view(expressions=["// bucket \n bucket(\"a\", 'M')"]) assert view.schema() == {"a": datetime, "bucket": date} assert view.to_columns() == { "a": [datetime(2020, 1, 1), None, None, datetime(2020, 3, 15)], @@ -1467,28 +1321,20 @@ def test_view_month_bucket_datetime_with_null(self): } def test_view_integer_expression(self): - table = Table({ - "x": int, - "y": date, - "z": float - }) + table = Table({"x": int, "y": date, "z": float}) view = table.view( expressions=[ - '// computed\n integer(2147483648)', - '// computed2\n integer(-2147483649)', - '// computed3 \n integer(123.456)', + "// computed\n integer(2147483648)", + "// computed2\n integer(-2147483649)", + "// computed3 \n integer(123.456)", '// computed4 \n integer("x")', '// computed5 \n integer("y")', - '// computed6 \n integer("z")' + '// computed6 \n integer("z")', ] ) - table.update({ - "x": [12136582], - "y": [date(2020, 6, 30)], - "z": [1.23456] - }) + table.update({"x": [12136582], "y": [date(2020, 6, 30)], "z": [1.23456]}) assert view.expression_schema() == { "computed": int, @@ -1509,33 +1355,23 @@ def test_view_integer_expression(self): assert result["computed6"] == [1] def test_view_float_expression(self): - table = Table({ - "w": datetime, - "x": int, - "y": date, - "z": float - }) + table = Table({"w": datetime, "x": int, "y": date, "z": float}) view = table.view( expressions=[ - '// computed\n float(2147483648)', - '// computed2\n float(-2147483649)', - '// computed3 \n float(123.456789123)', + "// computed\n float(2147483648)", + "// computed2\n float(-2147483649)", + "// computed3 \n float(123.456789123)", '// computed4 \n float("x")', '// computed5 \n float("y")', '// computed6 \n float("z")', - '// computed7 \n float("w")' + '// computed7 \n float("w")', ] ) dt = datetime(2018, 8, 12, 15, 32, 55) - table.update({ - "w": [dt], - "x": [12136582], - "y": [date(2020, 6, 30)], - "z": [1.23456] - }) + table.update({"w": [dt], "x": [12136582], "y": [date(2020, 6, 30)], "z": [1.23456]}) assert view.expression_schema() == { "computed": float, @@ -1559,23 +1395,13 @@ def test_view_float_expression(self): assert result["computed5"] == [132384030] assert result["computed6"] == [1.23456] assert result["computed7"] == [ms_timestamp] - + def test_view_date_expression(self): - table = Table({ - "x": [1] - }) + table = Table({"x": [1]}) - view = table.view( - expressions=[ - '// computed\n date(2020, 5, 30)', - '// computed2\n date(1997, 8, 31)' - ] - ) + view = table.view(expressions=["// computed\n date(2020, 5, 30)", "// computed2\n date(1997, 8, 31)"]) - assert view.expression_schema() == { - "computed": date, - "computed2": date - } + assert view.expression_schema() == {"computed": date, "computed2": date} result = view.to_dict() @@ -1583,56 +1409,33 @@ def test_view_date_expression(self): assert result["computed2"] == [datetime(1997, 8, 31)] def test_view_datetime_expression(self): - table = Table({ - "x": [1] - }) + table = Table({"x": [1]}) dt = datetime(2015, 11, 29, 23, 59, 59) seconds_timestamp = mktime(dt.timetuple()) + dt.microsecond / 1000000.0 ms_timestamp = int(seconds_timestamp * 1000) - view = table.view( - expressions=[ - '// computed\n datetime({})'.format(ms_timestamp) - ] - ) + view = table.view(expressions=["// computed\n datetime({})".format(ms_timestamp)]) - assert view.expression_schema() == { - "computed": datetime - } + assert view.expression_schema() == {"computed": datetime} result = view.to_dict() assert result["computed"] == [datetime(2015, 11, 29, 23, 59, 59)] def test_view_datetime_expression_roundtrip(self): - table = Table({ - "x": [datetime(2015, 11, 29, 23, 59, 59)] - }) + table = Table({"x": [datetime(2015, 11, 29, 23, 59, 59)]}) - view = table.view( - expressions=[ - '// computed\n datetime(float("x"))' - ] - ) + view = table.view(expressions=['// computed\n datetime(float("x"))']) - assert view.expression_schema() == { - "computed": datetime - } + assert view.expression_schema() == {"computed": datetime} result = view.to_dict() assert result["computed"] == [datetime(2015, 11, 29, 23, 59, 59)] def test_view_string_expression(self): - table = Table({ - "a": date, - "b": datetime, - "c": int, - "d": float, - "e": str, - "f": bool - }) + table = Table({"a": date, "b": datetime, "c": int, "d": float, "e": str, "f": bool}) view = table.view( expressions=[ @@ -1642,28 +1445,22 @@ def test_view_string_expression(self): '// computed4\n string("d")', '// computed5\n string("e")', '// computed6\n string("f")', - '// computed7\n string(1234.5678)' + "// computed7\n string(1234.5678)", ] ) - table.update({ - "a": [date(2020, 5, 30), date(2021, 7, 13)], - "b": [datetime(2015, 11, 29, 23, 59, 59), datetime(2016, 11, 29, 23, 59, 59)], - "c": [12345678, 1293879852], - "d": [1.2792013981, 19.218975981], - "e": ["abcdefghijklmnop", "def"], - "f": [False, True] - }) + table.update( + { + "a": [date(2020, 5, 30), date(2021, 7, 13)], + "b": [datetime(2015, 11, 29, 23, 59, 59), datetime(2016, 11, 29, 23, 59, 59)], + "c": [12345678, 1293879852], + "d": [1.2792013981, 19.218975981], + "e": ["abcdefghijklmnop", "def"], + "f": [False, True], + } + ) - assert view.expression_schema() == { - "computed": str, - "computed2": str, - "computed3": str, - "computed4": str, - "computed5": str, - "computed6": str, - "computed7": str - } + assert view.expression_schema() == {"computed": str, "computed2": str, "computed3": str, "computed4": str, "computed5": str, "computed6": str, "computed7": str} result = view.to_dict() @@ -1679,11 +1476,8 @@ def test_view_expession_multicomment(self): table = Table({"a": [1, 2, 3, 4]}) view = table.view(expressions=["var x := 1 + 2;\n// def\nx + 100 // cdefghijk"]) assert view.expression_schema() == {"var x := 1 + 2;\n// def\nx + 100 // cdefghijk": float} - assert view.to_columns() == { - "var x := 1 + 2;\n// def\nx + 100 // cdefghijk": [103, 103, 103, 103], - "a": [1, 2, 3, 4] - } - + assert view.to_columns() == {"var x := 1 + 2;\n// def\nx + 100 // cdefghijk": [103, 103, 103, 103], "a": [1, 2, 3, 4]} + def test_view_regex_email(self): endings = ["com", "net", "co.uk", "ie", "me", "io", "co"] data = ["{}@{}.{}".format(randstr(30, ascii_letters + "0123456789" + "._-"), randstr(10), choices(endings, k=1)[0]) for _ in range(100)] @@ -1692,17 +1486,12 @@ def test_view_regex_email(self): "// address\nsearch(\"a\", '^([a-zA-Z0-9._-]+)@')", "// domain\nsearch(\"a\", '@([a-zA-Z.]+)$')", "//is_email?\nmatch_all(\"a\", '^([a-zA-Z0-9._-]+)@([a-zA-Z.]+)$')", - "//has_at?\nmatch(\"a\", '@')" + "//has_at?\nmatch(\"a\", '@')", ] view = table.view(expressions=expressions) schema = view.expression_schema() - assert schema == { - "address": str, - "domain": str, - "is_email?": bool, - "has_at?": bool - } + assert schema == {"address": str, "domain": str, "is_email?": bool, "has_at?": bool} results = view.to_columns() @@ -1718,26 +1507,31 @@ def test_view_regex_email(self): def test_view_expression_number(self): def digits(): return randstr(4, "0123456789") - + data = [] for _ in range(1000): separator = "-" if random() > 0.5 else " " data.append("{}{}{}{}{}{}{}".format(digits(), separator, digits(), separator, digits(), separator, digits())) - + table = Table({"a": data}) - view = table.view(expressions=["""// parsed\n + view = table.view( + expressions=[ + """// parsed\n var parts[4]; parts[0] := search("a", '^([0-9]{4})[ -][0-9]{4}[ -][0-9]{4}[ -][0-9]{4}'); parts[1] := search("a", '^[0-9]{4}[ -]([0-9]{4})[ -][0-9]{4}[ -][0-9]{4}'); parts[2] := search("a", '^[0-9]{4}[ -][0-9]{4}[ -]([0-9]{4})[ -][0-9]{4}'); parts[3] := search("a", '^[0-9]{4}[ -][0-9]{4}[ -][0-9]{4}[ -]([0-9]{4})'); concat(parts[0], parts[1], parts[2], parts[3]) - """, "//is_number?\nmatch_all(\"a\", '^[0-9]{4}[ -][0-9]{4}[ -][0-9]{4}[ -][0-9]{4}')"]) + """, + "//is_number?\nmatch_all(\"a\", '^[0-9]{4}[ -][0-9]{4}[ -][0-9]{4}[ -][0-9]{4}')", + ] + ) schema = view.expression_schema() assert schema == {"parsed": str, "is_number?": bool} results = view.to_columns() - + for i in range(1000): source = results["a"][i] expected = re.sub(r"[ -]", "", source) @@ -1745,36 +1539,28 @@ def digits(): assert results["is_number?"][i] == True def test_view_expression_newlines(self): - table = Table({"a": [ - "abc\ndef", - "\n\n\n\nabc\ndef", - "abc\n\n\n\n\n\nabc\ndef\n\n\n\n", - None, - "def", - ], - "b": [ - "hello\tworld", - "\n\n\n\n\nhello\n\n\n\n\n\tworld", - "\tworld", - "world", - None, - ]}) - - view = table.view( - expressions=[ - "//c1\nsearch(\"a\", '(\ndef)')", - "//c2\nsearch(\"b\", '(\tworld)')", - "//c3\nmatch(\"a\", '\\n')", - "//c4\nmatch(\"b\", '\\n')" - ] + table = Table( + { + "a": [ + "abc\ndef", + "\n\n\n\nabc\ndef", + "abc\n\n\n\n\n\nabc\ndef\n\n\n\n", + None, + "def", + ], + "b": [ + "hello\tworld", + "\n\n\n\n\nhello\n\n\n\n\n\tworld", + "\tworld", + "world", + None, + ], + } ) - assert view.expression_schema() == { - "c1": str, - "c2": str, - "c3": bool, - "c4": bool - } + view = table.view(expressions=["//c1\nsearch(\"a\", '(\ndef)')", "//c2\nsearch(\"b\", '(\tworld)')", "//c3\nmatch(\"a\", '\\n')", "//c4\nmatch(\"b\", '\\n')"]) + + assert view.expression_schema() == {"c1": str, "c2": str, "c3": bool, "c4": bool} results = view.to_columns() assert results["c1"] == ["\ndef", "\ndef", "\ndef", None, None] @@ -1784,22 +1570,22 @@ def test_view_expression_newlines(self): def test_view_regex_substring(self): data = ["abc, def", "efg", "", None, "aaaaaaaaaaaaa"] - table = Table({ - "x": data - }) - view = table.view(expressions=[ - '//a\nsubstring(\'abcdef\', 0)', - '//abc\nsubstring(\'abcdef\', 3)', - '//b\nsubstring("x", 0)', - '//c\nsubstring("x", 5, 1)', - '//d\nsubstring("x", 100)', - '//e\nsubstring("x", 0, 10000)', - '//f\nsubstring("x", 5, 0)', - ]) + table = Table({"x": data}) + view = table.view( + expressions=[ + "//a\nsubstring('abcdef', 0)", + "//abc\nsubstring('abcdef', 3)", + '//b\nsubstring("x", 0)', + '//c\nsubstring("x", 5, 1)', + '//d\nsubstring("x", 100)', + '//e\nsubstring("x", 0, 10000)', + '//f\nsubstring("x", 5, 0)', + ] + ) results = view.to_columns() - assert results["a"] == ['abcdef' for _ in data] - assert results["abc"] == ['def' for _ in data] + assert results["a"] == ["abcdef" for _ in data] + assert results["abc"] == ["def" for _ in data] assert results["b"] == [d if d else None for d in data] assert results["c"] == ["d", None, None, None, "a"] assert results["d"] == [None for _ in data] @@ -1813,7 +1599,7 @@ def test_view_regex_email_substr(self): data = ["{}@{}.{}".format(randstr(30, ascii_letters + "0123456789" + "._-"), randstr(10), choices(endings, k=1)[0]) for _ in range(100)] table = Table({"a": data}) expressions = [ - "// address\nvar vec[2]; indexof(\"a\", '^([a-zA-Z0-9._-]+)@', vec) ? substring(\"a\", vec[0], vec[1] - vec[0] + 1) : null", + '// address\nvar vec[2]; indexof("a", \'^([a-zA-Z0-9._-]+)@\', vec) ? substring("a", vec[0], vec[1] - vec[0] + 1) : null', """// ending var domain := search(\"a\", '@([a-zA-Z.]+)$'); var len := length(domain); @@ -1821,7 +1607,7 @@ def test_view_regex_email_substr(self): search(domain, '[.](.*)$'); } else { 'not found'; - }""" + }""", ] view = table.view(expressions=expressions) @@ -1844,13 +1630,13 @@ def test_view_regex_email_substr(self): def test_view_expressions_replace(self): def digits(): return randstr(4, "0123456789") - + data = [] for _ in range(1000): separator = "-" if random() > 0.5 else " " data.append("{}{}{}{}{}{}{}".format(digits(), separator, digits(), separator, digits(), separator, digits())) - + table = Table({"a": data, "b": [str(i) for i in range(1000)]}) expressions = [ """//w @@ -1860,7 +1646,7 @@ def digits(): """//y replace("a", '[a-z]{4}$', "b")""", """//z - var x := 'long string, very cool!'; replace("a", '^[0-9]{4}', x)""" + var x := 'long string, very cool!'; replace("a", '^[0-9]{4}', x)""", ] validate = table.validate_expressions(expressions) @@ -1880,17 +1666,17 @@ def digits(): "z": str, } results = view.to_columns() - + for i in range(1000): source = results["a"][i] idx = results["b"][i] - assert results["w"][i] == "abcdef-hijk"; + assert results["w"][i] == "abcdef-hijk" assert results["x"][i] == re.sub(r"[0-9]{4}$", idx, source, 1) assert results["y"][i] == source assert results["z"][i] == re.sub(r"^[0-9]{4}", "long string, very cool!", source, 1) def test_view_replace_invalid(self): - table = Table({"a": "string", "b": "string"}); + table = Table({"a": "string", "b": "string"}) expressions = [ """//v replace('abc-def-hijk', '-', 123)""", @@ -1909,13 +1695,13 @@ def test_view_replace_invalid(self): def test_view_expressions_replace_all(self): def digits(): return randstr(4, "0123456789") - + data = [] for _ in range(1000): separator = "-" if random() > 0.5 else " " data.append("{}{}{}{}{}{}{}".format(digits(), separator, digits(), separator, digits(), separator, digits())) - + table = Table({"a": data, "b": [str(i) for i in range(1000)]}) expressions = [ """//w @@ -1925,7 +1711,7 @@ def digits(): """//y replace_all("a", '[a-z]{4}$', "b")""", """//z - var x := 'long string, very cool!'; replace_all("a", '^[0-9]{4}', x)""" + var x := 'long string, very cool!'; replace_all("a", '^[0-9]{4}', x)""", ] validate = table.validate_expressions(expressions) @@ -1946,17 +1732,17 @@ def digits(): } results = view.to_columns() - + for i in range(1000): source = results["a"][i] idx = results["b"][i] - assert results["w"][i] == "abcdefhijk"; + assert results["w"][i] == "abcdefhijk" assert results["x"][i] == re.sub(r"[0-9]{4}$", idx, source) assert results["y"][i] == source assert results["z"][i] == re.sub(r"^[0-9]{4}", "long string, very cool!", source) def test_view_replace_invalid(self): - table = Table({"a": "string", "b": "string"}); + table = Table({"a": "string", "b": "string"}) expressions = [ """//v replace_all('abc-def-hijk', '-', 123)""", diff --git a/python/perspective/perspective/tests/viewer/__init__.py b/python/perspective/perspective/tests/viewer/__init__.py index 08a51ceca3..284e70816f 100644 --- a/python/perspective/perspective/tests/viewer/__init__.py +++ b/python/perspective/perspective/tests/viewer/__init__.py @@ -9,4 +9,3 @@ # ┃ This file is part of the Perspective library, distributed under the terms ┃ # ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - diff --git a/python/perspective/perspective/tests/viewer/test_validate.py b/python/perspective/perspective/tests/viewer/test_validate.py index f032e60b33..5edc23ec48 100644 --- a/python/perspective/perspective/tests/viewer/test_validate.py +++ b/python/perspective/perspective/tests/viewer/test_validate.py @@ -17,7 +17,6 @@ class TestValidate: - def test_validate_plugin_valid_instance(self): assert validate.validate_plugin(Plugin.XBAR) == "X Bar" diff --git a/python/perspective/perspective/tests/viewer/test_viewer.py b/python/perspective/perspective/tests/viewer/test_viewer.py index 812cace724..8ba4b6ad36 100644 --- a/python/perspective/perspective/tests/viewer/test_viewer.py +++ b/python/perspective/perspective/tests/viewer/test_viewer.py @@ -16,7 +16,6 @@ class TestViewer: - def test_viewer_get_table(self): table = Table({"a": [1, 2, 3]}) viewer = PerspectiveViewer() @@ -52,12 +51,7 @@ def test_viewer_load_named_data(self): def test_viewer_load_schema(self): viewer = PerspectiveViewer() - viewer.load({ - "a": str, - "b": int, - "c": bool, - "d": str - }) + viewer.load({"a": str, "b": int, "c": bool, "d": str}) for col in viewer.columns: assert col in ["a", "b", "c", "d"] @@ -84,6 +78,7 @@ def test_viewer_load_clears_state(self): viewer.load({"b": [1, 2, 3]}) assert viewer.group_by == [] assert viewer.theme == "Pro Dark" # should not break UI + def test_viewer_load_np(self): table = Table({"a": np.arange(1, 100)}) viewer = PerspectiveViewer() @@ -119,9 +114,7 @@ def test_viewer_update_dict(self): viewer.update({"a": [4, 5, 6]}) assert table.size() == 6 assert viewer.table.size() == 6 - assert viewer.table.view().to_dict() == { - "a": [1, 2, 3, 4, 5, 6] - } + assert viewer.table.view().to_dict() == {"a": [1, 2, 3, 4, 5, 6]} def test_viewer_update_list(self): table = Table({"a": [1, 2, 3]}) @@ -130,9 +123,7 @@ def test_viewer_update_list(self): viewer.update([{"a": 4}, {"a": 5}, {"a": 6}]) assert table.size() == 6 assert viewer.table.size() == 6 - assert viewer.table.view().to_dict() == { - "a": [1, 2, 3, 4, 5, 6] - } + assert viewer.table.view().to_dict() == {"a": [1, 2, 3, 4, 5, 6]} def test_viewer_update_df(self): table = Table({"a": [1, 2, 3]}) @@ -141,9 +132,7 @@ def test_viewer_update_df(self): viewer.update(pd.DataFrame({"a": [4, 5, 6]})) assert table.size() == 6 assert viewer.table.size() == 6 - assert viewer.table.view().to_dict() == { - "a": [1, 2, 3, 4, 5, 6] - } + assert viewer.table.view().to_dict() == {"a": [1, 2, 3, 4, 5, 6]} def test_viewer_update_dict_partial(self): table = Table({"a": [1, 2, 3], "b": [5, 6, 7]}, index="a") @@ -152,10 +141,7 @@ def test_viewer_update_dict_partial(self): viewer.update({"a": [1, 2, 3], "b": [8, 9, 10]}) assert table.size() == 3 assert viewer.table.size() == 3 - assert viewer.table.view().to_dict() == { - "a": [1, 2, 3], - "b": [8, 9, 10] - } + assert viewer.table.view().to_dict() == {"a": [1, 2, 3], "b": [8, 9, 10]} # clear @@ -165,9 +151,7 @@ def test_viewer_clear(self): viewer.load(table) viewer.clear() assert viewer.table.size() == 0 - assert viewer.table.schema() == { - "a": int - } + assert viewer.table.schema() == {"a": int} # replace @@ -177,12 +161,8 @@ def test_viewer_replace(self): viewer.load(table) viewer.replace({"a": [4, 5, 6]}) assert viewer.table.size() == 3 - assert viewer.table.schema() == { - "a": int - } - assert viewer.table.view().to_dict() == { - "a": [4, 5, 6] - } + assert viewer.table.schema() == {"a": int} + assert viewer.table.view().to_dict() == {"a": [4, 5, 6]} # reset @@ -218,11 +198,7 @@ def test_viewer_delete_without_table(self): def test_save_restore(self): table = Table({"a": [1, 2, 3]}) - viewer = PerspectiveViewer( - plugin="X Bar", - filter=[["a", "==", 2]], - expressions=['"a" * 2'] - ) + viewer = PerspectiveViewer(plugin="X Bar", filter=[["a", "==", 2]], expressions=['"a" * 2']) viewer.load(table) # Save config @@ -249,13 +225,7 @@ def test_save_restore_plugin_config(self): viewer = PerspectiveViewer(plugin="Datagrid", plugin_config={"columns": {"a": {"fixed": 4}}}) config = viewer.save() - assert config["plugin_config"] == { - "columns": { - "a": { - "fixed": 4 - } - } - } + assert config["plugin_config"] == {"columns": {"a": {"fixed": 4}}} viewer.reset() assert viewer.plugin_config == {} diff --git a/python/perspective/perspective/tests/widget/__init__.py b/python/perspective/perspective/tests/widget/__init__.py index 08a51ceca3..284e70816f 100644 --- a/python/perspective/perspective/tests/widget/__init__.py +++ b/python/perspective/perspective/tests/widget/__init__.py @@ -9,4 +9,3 @@ # ┃ This file is part of the Perspective library, distributed under the terms ┃ # ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - diff --git a/python/perspective/perspective/tests/widget/test_widget.py b/python/perspective/perspective/tests/widget/test_widget.py index d157a0d303..9eed5fbdcf 100644 --- a/python/perspective/perspective/tests/widget/test_widget.py +++ b/python/perspective/perspective/tests/widget/test_widget.py @@ -30,30 +30,14 @@ def test_widget(self): widget = PerspectiveWidget(data, plugin="X Bar") assert widget.plugin == "X Bar" load_msg = widget._make_load_message() - assert load_msg.to_dict() == { - "id": -2, - "type": "table", - "data": { - "table_name": widget.table_name, - "options": {} - } - } + assert load_msg.to_dict() == {"id": -2, "type": "table", "data": {"table_name": widget.table_name, "options": {}}} def test_widget_indexed(self): data = {"a": np.arange(0, 50)} widget = PerspectiveWidget(data, plugin="X Bar", index="a") assert widget.plugin == "X Bar" load_msg = widget._make_load_message() - assert load_msg.to_dict() == { - "id": -2, - "type": "table", - "data": { - "table_name": widget.table_name, - "options": { - "index": "a" - } - } - } + assert load_msg.to_dict() == {"id": -2, "type": "table", "data": {"table_name": widget.table_name, "options": {"index": "a"}}} def test_widget_no_data(self): widget = PerspectiveWidget(None, plugin="X Bar", group_by=["a"]) @@ -61,14 +45,7 @@ def test_widget_no_data(self): assert widget.group_by == ["a"] def test_widget_schema(self): - schema = { - "a": int, - "b": float, - "c": bool, - "d": date, - "e": datetime, - "f": str - } + schema = {"a": int, "b": float, "c": bool, "d": date, "e": datetime, "f": str} widget = PerspectiveWidget(schema) assert widget.table.schema() == schema @@ -101,14 +78,7 @@ def test_widget_eventual_data(self): widget.load(table) load_msg = widget._make_load_message() - assert load_msg.to_dict() == { - "id": -2, - "type": "table", - "data": { - "table_name": widget.table_name, - "options": {} - } - } + assert load_msg.to_dict() == {"id": -2, "type": "table", "data": {"table_name": widget.table_name, "options": {}}} def test_widget_eventual_data_server(self): widget = PerspectiveWidget(None, plugin="X Bar", server=True) @@ -120,7 +90,7 @@ def test_widget_eventual_data_server(self): "type": "table", "data": { "table_name": widget.table_name, - } + }, } def test_widget_eventual_data_indexed(self): @@ -128,16 +98,7 @@ def test_widget_eventual_data_indexed(self): assert widget.plugin == "X Bar" widget.load({"a": np.arange(0, 50)}, index="a") load_msg = widget._make_load_message() - assert load_msg.to_dict() == { - "id": -2, - "type": "table", - "data": { - "table_name": widget.table_name, - "options": { - "index": "a" - } - } - } + assert load_msg.to_dict() == {"id": -2, "type": "table", "data": {"table_name": widget.table_name, "options": {"index": "a"}}} def test_widget_eventual_table_indexed(self): table = Table({"a": np.arange(0, 50)}, index="a") @@ -145,46 +106,21 @@ def test_widget_eventual_table_indexed(self): assert widget.plugin == "X Bar" widget.load(table) load_msg = widget._make_load_message() - assert load_msg.to_dict() == { - "id": -2, - "type": "table", - "data": { - "table_name": widget.table_name, - "options": { - "index": "a" - } - } - } + assert load_msg.to_dict() == {"id": -2, "type": "table", "data": {"table_name": widget.table_name, "options": {"index": "a"}}} def test_widget_load_table(self): table = Table({"a": np.arange(0, 50)}) widget = PerspectiveWidget(table, plugin="X Bar") assert widget.plugin == "X Bar" load_msg = widget._make_load_message() - assert load_msg.to_dict() == { - "id": -2, - "type": "table", - "data": { - "table_name": widget.table_name, - "options": {} - } - } + assert load_msg.to_dict() == {"id": -2, "type": "table", "data": {"table_name": widget.table_name, "options": {}}} def test_widget_load_table_indexed(self): table = Table({"a": np.arange(0, 50)}, index="a") widget = PerspectiveWidget(table, plugin="X Bar") assert widget.plugin == "X Bar" load_msg = widget._make_load_message() - assert load_msg.to_dict() == { - "id": -2, - "type": "table", - "data": { - "table_name": widget.table_name, - "options": { - "index": "a" - } - } - } + assert load_msg.to_dict() == {"id": -2, "type": "table", "data": {"table_name": widget.table_name, "options": {"index": "a"}}} def test_widget_load_table_ignore_limit(self): table = Table({"a": np.arange(0, 50)}) @@ -211,13 +147,7 @@ def test_widget_load_table_server(self): table = Table({"a": np.arange(0, 50)}) widget = PerspectiveWidget(table, server=True) load_msg = widget._make_load_message() - assert load_msg.to_dict() == { - "id": -2, - "type": "table", - "data": { - "table_name": widget.table_name - } - } + assert load_msg.to_dict() == {"id": -2, "type": "table", "data": {"table_name": widget.table_name}} def test_widget_no_data_with_server(self): # should fail @@ -235,13 +165,7 @@ def test_widget_eventual_data_with_server(self): # then succeed widget.load(Table({"a": np.arange(0, 50)})) load_msg = widget._make_load_message() - assert load_msg.to_dict() == { - "id": -2, - "type": "table", - "data": { - "table_name": widget.table_name - } - } + assert load_msg.to_dict() == {"id": -2, "type": "table", "data": {"table_name": widget.table_name}} # clear @@ -276,9 +200,7 @@ def test_widget_replace_server(self): def test_widget_delete(self): data = {"a": np.arange(0, 50)} widget = PerspectiveWidget(data) - mocked_post = partial(mock_post, assert_msg={ - "cmd": "delete" - }) + mocked_post = partial(mock_post, assert_msg={"cmd": "delete"}) widget.post = MethodType(mocked_post, widget) widget.delete() assert widget.table is None @@ -294,9 +216,7 @@ def test_widget_delete_with_view(self): assert len(widget.manager._views) == 1 - mocked_post = partial(mock_post, assert_msg={ - "cmd": "delete" - }) + mocked_post = partial(mock_post, assert_msg={"cmd": "delete"}) widget.post = MethodType(mocked_post, widget) widget.delete() diff --git a/python/perspective/perspective/tests/widget/test_widget_pandas.py b/python/perspective/perspective/tests/widget/test_widget_pandas.py index f89c3fe626..e7e63dc3d6 100644 --- a/python/perspective/perspective/tests/widget/test_widget_pandas.py +++ b/python/perspective/perspective/tests/widget/test_widget_pandas.py @@ -17,26 +17,86 @@ class TestWidgetPandas: - def test_widget_load_table_df(self, superstore): table = Table(superstore) widget = PerspectiveWidget(table) - assert widget.table.schema() == {'index': int, 'Country': str, 'Region': str, 'Category': str, 'City': str, 'Customer ID': str, 'Discount': float, - 'Order Date': date, 'Order ID': str, 'Postal Code': str, 'Product ID': str, 'Profit': float, 'Quantity': int, - 'Row ID': int, 'Sales': int, 'Segment': str, 'Ship Date': date, 'Ship Mode': str, 'State': str, 'Sub-Category': str} - - assert sorted(widget.columns) == sorted(['index', 'Category', 'City', 'Country', 'Customer ID', 'Discount', 'Order Date', 'Order ID', 'Postal Code', - 'Product ID', 'Profit', 'Quantity', 'Region', 'Row ID', 'Sales', 'Segment', 'Ship Date', - 'Ship Mode', 'State', 'Sub-Category']) + assert widget.table.schema() == { + "index": int, + "Country": str, + "Region": str, + "Category": str, + "City": str, + "Customer ID": str, + "Discount": float, + "Order Date": date, + "Order ID": str, + "Postal Code": str, + "Product ID": str, + "Profit": float, + "Quantity": int, + "Row ID": int, + "Sales": int, + "Segment": str, + "Ship Date": date, + "Ship Mode": str, + "State": str, + "Sub-Category": str, + } + + assert sorted(widget.columns) == sorted( + [ + "index", + "Category", + "City", + "Country", + "Customer ID", + "Discount", + "Order Date", + "Order ID", + "Postal Code", + "Product ID", + "Profit", + "Quantity", + "Region", + "Row ID", + "Sales", + "Segment", + "Ship Date", + "Ship Mode", + "State", + "Sub-Category", + ] + ) view = widget.table.view() assert view.num_rows() == len(superstore) assert view.num_columns() == len(superstore.columns) + 1 # index def test_widget_load_data_df(self, superstore): widget = PerspectiveWidget(superstore) - assert sorted(widget.columns) == sorted(['index', 'Category', 'City', 'Country', 'Customer ID', 'Discount', 'Order Date', 'Order ID', 'Postal Code', - 'Product ID', 'Profit', 'Quantity', 'Region', 'Row ID', 'Sales', 'Segment', 'Ship Date', - 'Ship Mode', 'State', 'Sub-Category']) + assert sorted(widget.columns) == sorted( + [ + "index", + "Category", + "City", + "Country", + "Customer ID", + "Discount", + "Order Date", + "Order ID", + "Postal Code", + "Product ID", + "Profit", + "Quantity", + "Region", + "Row ID", + "Sales", + "Segment", + "Ship Date", + "Ship Mode", + "State", + "Sub-Category", + ] + ) view = widget.table.view() assert view.num_rows() == len(superstore) assert view.num_columns() == 20 @@ -44,7 +104,7 @@ def test_widget_load_data_df(self, superstore): def test_widget_load_series(self, superstore): series = pd.Series(superstore["Profit"].values, name="profit") widget = PerspectiveWidget(series) - assert widget.table.schema() == {'index': int, 'profit': float} + assert widget.table.schema() == {"index": int, "profit": float} assert sorted(widget.columns) == sorted(["index", "profit"]) view = widget.table.view() @@ -52,93 +112,141 @@ def test_widget_load_series(self, superstore): assert view.num_columns() == 2 def test_widget_load_pivot_table(self, superstore): - pivot_table = pd.pivot_table(superstore, values='Discount', index=['Country', 'Region'], columns=['Category', 'Segment']) + pivot_table = pd.pivot_table(superstore, values="Discount", index=["Country", "Region"], columns=["Category", "Segment"]) widget = PerspectiveWidget(pivot_table) - assert widget.group_by == ['Country', 'Region'] - assert widget.split_by == ['Category', 'Segment'] - assert widget.columns == ['value'] + assert widget.group_by == ["Country", "Region"] + assert widget.split_by == ["Category", "Segment"] + assert widget.columns == ["value"] # table should host flattened data view = widget.table.view() assert view.num_rows() == 60 assert view.num_columns() == 6 def test_widget_load_pivot_table_with_user_pivots(self, superstore): - pivot_table = pd.pivot_table(superstore, values='Discount', index=['Country', 'Region'], columns='Category') + pivot_table = pd.pivot_table(superstore, values="Discount", index=["Country", "Region"], columns="Category") widget = PerspectiveWidget(pivot_table, group_by=["Category", "Segment"]) - assert widget.group_by == ['Category', 'Segment'] + assert widget.group_by == ["Category", "Segment"] assert widget.split_by == [] - assert widget.columns == ['index', 'Country', 'Region', 'Financials', 'Industrials', 'Technology'] + assert widget.columns == ["index", "Country", "Region", "Financials", "Industrials", "Technology"] # table should host flattened data view = widget.table.view() assert view.num_rows() == 5 assert view.num_columns() == 6 def test_widget_load_group_by(self, superstore): - df_pivoted = superstore.set_index(['Country', 'Region']) + df_pivoted = superstore.set_index(["Country", "Region"]) widget = PerspectiveWidget(df_pivoted) - assert widget.group_by == ['Country', 'Region'] + assert widget.group_by == ["Country", "Region"] assert widget.split_by == [] - assert sorted(widget.columns) == sorted(['index', 'Category', 'Country', 'City', 'Customer ID', 'Discount', 'Order Date', 'Order ID', 'Postal Code', - 'Product ID', 'Profit', 'Quantity', 'Region', 'Row ID', 'Sales', 'Segment', 'Ship Date', - 'Ship Mode', 'State', 'Sub-Category']) + assert sorted(widget.columns) == sorted( + [ + "index", + "Category", + "Country", + "City", + "Customer ID", + "Discount", + "Order Date", + "Order ID", + "Postal Code", + "Product ID", + "Profit", + "Quantity", + "Region", + "Row ID", + "Sales", + "Segment", + "Ship Date", + "Ship Mode", + "State", + "Sub-Category", + ] + ) assert widget.table.size() == 100 view = widget.table.view() assert view.num_rows() == len(superstore) assert view.num_columns() == len(superstore.columns) + 1 # index def test_widget_load_group_by_with_user_pivots(self, superstore): - df_pivoted = superstore.set_index(['Country', 'Region']) + df_pivoted = superstore.set_index(["Country", "Region"]) widget = PerspectiveWidget(df_pivoted, group_by=["Category", "Segment"]) - assert widget.group_by == ['Category', 'Segment'] + assert widget.group_by == ["Category", "Segment"] assert widget.split_by == [] - assert sorted(widget.columns) == sorted(['index', 'Category', 'Country', 'City', 'Customer ID', 'Discount', 'Order Date', 'Order ID', 'Postal Code', - 'Product ID', 'Profit', 'Quantity', 'Region', 'Row ID', 'Sales', 'Segment', 'Ship Date', - 'Ship Mode', 'State', 'Sub-Category']) + assert sorted(widget.columns) == sorted( + [ + "index", + "Category", + "Country", + "City", + "Customer ID", + "Discount", + "Order Date", + "Order ID", + "Postal Code", + "Product ID", + "Profit", + "Quantity", + "Region", + "Row ID", + "Sales", + "Segment", + "Ship Date", + "Ship Mode", + "State", + "Sub-Category", + ] + ) assert widget.table.size() == 100 view = widget.table.view() assert view.num_rows() == len(superstore) assert view.num_columns() == len(superstore.columns) + 1 # index def test_widget_load_split_by(self, superstore): - arrays = [np.array(['bar', 'bar', 'bar', 'bar', 'baz', 'baz', 'baz', 'baz', 'foo', 'foo', 'foo', 'foo', 'qux', 'qux', 'qux', 'qux']), - np.array(['one', 'one', 'two', 'two', 'one', 'one', 'two', 'two', 'one', 'one', 'two', 'two', 'one', 'one', 'two', 'two']), - np.array(['X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y'])] + arrays = [ + np.array(["bar", "bar", "bar", "bar", "baz", "baz", "baz", "baz", "foo", "foo", "foo", "foo", "qux", "qux", "qux", "qux"]), + np.array(["one", "one", "two", "two", "one", "one", "two", "two", "one", "one", "two", "two", "one", "one", "two", "two"]), + np.array(["X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y"]), + ] tuples = list(zip(*arrays)) - index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second', 'third']) - df_both = pd.DataFrame(np.random.randn(3, 16), index=['A', 'B', 'C'], columns=index) + index = pd.MultiIndex.from_tuples(tuples, names=["first", "second", "third"]) + df_both = pd.DataFrame(np.random.randn(3, 16), index=["A", "B", "C"], columns=index) widget = PerspectiveWidget(df_both) - assert widget.columns == ['value'] - assert widget.split_by == ['first', 'second', 'third'] - assert widget.group_by == ['index'] + assert widget.columns == ["value"] + assert widget.split_by == ["first", "second", "third"] + assert widget.group_by == ["index"] def test_widget_load_split_by_preserve_user_settings(self, superstore): - arrays = [np.array(['bar', 'bar', 'bar', 'bar', 'baz', 'baz', 'baz', 'baz', 'foo', 'foo', 'foo', 'foo', 'qux', 'qux', 'qux', 'qux']), - np.array(['one', 'one', 'two', 'two', 'one', 'one', 'two', 'two', 'one', 'one', 'two', 'two', 'one', 'one', 'two', 'two']), - np.array(['X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y'])] + arrays = [ + np.array(["bar", "bar", "bar", "bar", "baz", "baz", "baz", "baz", "foo", "foo", "foo", "foo", "qux", "qux", "qux", "qux"]), + np.array(["one", "one", "two", "two", "one", "one", "two", "two", "one", "one", "two", "two", "one", "one", "two", "two"]), + np.array(["X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y"]), + ] tuples = list(zip(*arrays)) - index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second', 'third']) - df_both = pd.DataFrame(np.random.randn(3, 16), index=['A', 'B', 'C'], columns=index) + index = pd.MultiIndex.from_tuples(tuples, names=["first", "second", "third"]) + df_both = pd.DataFrame(np.random.randn(3, 16), index=["A", "B", "C"], columns=index) widget = PerspectiveWidget(df_both, columns=["first", "third"]) - assert widget.columns == ['first', "third"] - assert widget.split_by == ['first', 'second', 'third'] - assert widget.group_by == ['index'] + assert widget.columns == ["first", "third"] + assert widget.split_by == ["first", "second", "third"] + assert widget.group_by == ["index"] def test_pivottable_values_index(self, superstore): - arrays = {'A':['bar', 'bar', 'bar', 'bar', 'baz', 'baz', 'baz', 'baz', 'foo', 'foo', 'foo', 'foo', 'qux', 'qux', 'qux', 'qux'], - 'B':['one', 'one', 'two', 'two', 'one', 'one', 'two', 'two', 'one', 'one', 'two', 'two', 'one', 'one', 'two', 'two'], - 'C':['X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y'], - 'D':np.arange(16)} + arrays = { + "A": ["bar", "bar", "bar", "bar", "baz", "baz", "baz", "baz", "foo", "foo", "foo", "foo", "qux", "qux", "qux", "qux"], + "B": ["one", "one", "two", "two", "one", "one", "two", "two", "one", "one", "two", "two", "one", "one", "two", "two"], + "C": ["X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y", "X", "Y"], + "D": np.arange(16), + } df = pd.DataFrame(arrays) - df_pivot = df.pivot_table(values=['D'], index=['A'], columns=['B','C'], aggfunc={'D':'count'}) + df_pivot = df.pivot_table(values=["D"], index=["A"], columns=["B", "C"], aggfunc={"D": "count"}) widget = PerspectiveWidget(df_pivot) - assert widget.columns == ['value'] - assert widget.split_by == ['B', 'C'] - assert widget.group_by == ['A'] + assert widget.columns == ["value"] + assert widget.split_by == ["B", "C"] + assert widget.group_by == ["A"] def test_pivottable_multi_values(self, superstore): - pt = pd.pivot_table(superstore, values = ['Discount','Sales'], index=['Country','Region'],aggfunc={'Discount':'count','Sales':'sum'},columns=["State","Quantity"]) + pt = pd.pivot_table(superstore, values=["Discount", "Sales"], index=["Country", "Region"], aggfunc={"Discount": "count", "Sales": "sum"}, columns=["State", "Quantity"]) widget = PerspectiveWidget(pt) - assert widget.columns == ['Discount', 'Sales'] - assert widget.split_by == ['State', 'Quantity'] - assert widget.group_by == ['Country', 'Region'] + assert widget.columns == ["Discount", "Sales"] + assert widget.split_by == ["State", "Quantity"] + assert widget.group_by == ["Country", "Region"] diff --git a/python/perspective/pyproject.toml b/python/perspective/pyproject.toml index a1b7558db5..698b6873a9 100644 --- a/python/perspective/pyproject.toml +++ b/python/perspective/pyproject.toml @@ -23,11 +23,6 @@ build-backend = "jupyter_packaging.build_api" line-length = 200 target-version = ['py37', 'py38'] include = '\.pyi?$' -extend-exclude = ''' -/( -| perspective/tests -)/ -''' [tool.pytest.ini_options] asyncio_mode = 'strict' diff --git a/python/perspective/setup.cfg b/python/perspective/setup.cfg index 5b19f4a693..22b5bc6184 100644 --- a/python/perspective/setup.cfg +++ b/python/perspective/setup.cfg @@ -8,7 +8,6 @@ inplace=0 [flake8] ignore=E203, W503 max-line-length=200 -exclude=perspective/tests/ per-file-ignores = __init__.py: F401, F403 libpsp.py: F401, F403 diff --git a/tools/perspective-scripts/fix_python.mjs b/tools/perspective-scripts/fix_python.mjs index 2e5633c66e..0d8623449f 100644 --- a/tools/perspective-scripts/fix_python.mjs +++ b/tools/perspective-scripts/fix_python.mjs @@ -15,7 +15,7 @@ import * as url from "url"; const __dirname = url.fileURLToPath(new URL(".", import.meta.url)).slice(0, -1); -const cmd = sh`black perspective bench setup.py --exclude tests`; +const cmd = sh`black perspective bench setup.py`; if (process.env.PSP_DOCKER) { cmd = sh`cd python/perspective`.sh(cmd);