perspective-python 4.2.0__cp311-abi3-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- perspective/__init__.py +396 -0
- perspective/extension/finos-perspective-nbextension.json +5 -0
- perspective/handlers/__init__.py +11 -0
- perspective/handlers/aiohttp.py +61 -0
- perspective/handlers/starlette.py +55 -0
- perspective/handlers/tornado.py +184 -0
- perspective/perspective.pyd +0 -0
- perspective/templates/exported_widget.html.template +35 -0
- perspective/tests/__init__.py +11 -0
- perspective/tests/async/test_async_client.py +83 -0
- perspective/tests/async/test_websocket_client.py +124 -0
- perspective/tests/conftest.py +272 -0
- perspective/tests/core/__init__.py +11 -0
- perspective/tests/core/test_async.py +351 -0
- perspective/tests/multi_threaded/__init__.py +11 -0
- perspective/tests/multi_threaded/test_multi_threaded.py +201 -0
- perspective/tests/server/__init__.py +11 -0
- perspective/tests/server/test_server.py +1016 -0
- perspective/tests/server/test_session.py +110 -0
- perspective/tests/table/__init__.py +11 -0
- perspective/tests/table/arrow/date32.arrow +0 -0
- perspective/tests/table/arrow/date64.arrow +0 -0
- perspective/tests/table/arrow/dict.arrow +0 -0
- perspective/tests/table/arrow/dict_update.arrow +0 -0
- perspective/tests/table/arrow/int_float_str.arrow +0 -0
- perspective/tests/table/arrow/int_float_str_file.arrow +0 -0
- perspective/tests/table/arrow/int_float_str_update.arrow +0 -0
- perspective/tests/table/object_sequence.py +402 -0
- perspective/tests/table/test_column_paths.py +89 -0
- perspective/tests/table/test_delete.py +124 -0
- perspective/tests/table/test_exception.py +65 -0
- perspective/tests/table/test_leaks.py +54 -0
- perspective/tests/table/test_ports.py +178 -0
- perspective/tests/table/test_remove.py +102 -0
- perspective/tests/table/test_table.py +641 -0
- perspective/tests/table/test_table_arrow.py +503 -0
- perspective/tests/table/test_table_datetime.py +2409 -0
- perspective/tests/table/test_table_infer.py +201 -0
- perspective/tests/table/test_table_limit.py +45 -0
- perspective/tests/table/test_table_numpy.py +1022 -0
- perspective/tests/table/test_table_pandas.py +1018 -0
- perspective/tests/table/test_table_polars.py +251 -0
- perspective/tests/table/test_table_view_table.py +130 -0
- perspective/tests/table/test_to_arrow.py +417 -0
- perspective/tests/table/test_to_arrow_lz4.py +32 -0
- perspective/tests/table/test_to_format.py +1024 -0
- perspective/tests/table/test_to_polars.py +26 -0
- perspective/tests/table/test_update.py +545 -0
- perspective/tests/table/test_update_arrow.py +980 -0
- perspective/tests/table/test_update_pandas.py +211 -0
- perspective/tests/table/test_view.py +2261 -0
- perspective/tests/table/test_view_expression.py +1940 -0
- perspective/tests/test_dependencies.py +53 -0
- perspective/tests/viewer/__init__.py +11 -0
- perspective/tests/viewer/test_viewer.py +246 -0
- perspective/tests/widget/__init__.py +11 -0
- perspective/tests/widget/test_widget.py +278 -0
- perspective/tests/widget/test_widget_pandas.py +453 -0
- perspective/virtual_servers/__init__.py +134 -0
- perspective/virtual_servers/clickhouse.py +245 -0
- perspective/virtual_servers/duckdb.py +236 -0
- perspective/widget/__init__.py +349 -0
- perspective/widget/viewer/__init__.py +15 -0
- perspective/widget/viewer/validate.py +22 -0
- perspective/widget/viewer/viewer.py +343 -0
- perspective/widget/viewer/viewer_traitlets.py +101 -0
- perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/install.json +5 -0
- perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/package.json +71 -0
- perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/253.5f5c9e80605aa4106a28.js +2 -0
- perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/253.5f5c9e80605aa4106a28.js.LICENSE.txt +25 -0
- perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/523.c030af5d3c4f67ff83f6.js +1 -0
- perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/remoteEntry.95a8ea1b44d96032833f.js +1 -0
- perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/style.js +4 -0
- perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/third-party-licenses.json +16 -0
- perspective_python-4.2.0.dist-info/METADATA +27 -0
- perspective_python-4.2.0.dist-info/RECORD +79 -0
- perspective_python-4.2.0.dist-info/WHEEL +4 -0
- perspective_python-4.2.0.dist-info/licenses/LICENSE.md +193 -0
- perspective_python-4.2.0.dist-info/licenses/LICENSE_THIRDPARTY_cargo.yml +17395 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
# ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
# ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
# ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
# ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
# ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
# ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
# ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
# ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
# ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
# ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
import pandas as pd
|
|
15
|
+
from datetime import date, datetime
|
|
16
|
+
from pytest import mark
|
|
17
|
+
import pytest
|
|
18
|
+
import perspective as psp
|
|
19
|
+
|
|
20
|
+
client = psp.Server().new_local_client()
|
|
21
|
+
Table = client.table
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class TestUpdatePandas(object):
|
|
25
|
+
def test_update_df(self):
|
|
26
|
+
tbl = Table({"a": [1, 2, 3, 4]})
|
|
27
|
+
|
|
28
|
+
update_data = pd.DataFrame({"a": [5, 6, 7, 8]})
|
|
29
|
+
|
|
30
|
+
tbl.update(update_data)
|
|
31
|
+
|
|
32
|
+
assert tbl.view().to_columns() == {"a": [1, 2, 3, 4, 5, 6, 7, 8]}
|
|
33
|
+
|
|
34
|
+
def test_update_df_i32_vs_i64(self):
|
|
35
|
+
tbl = Table({"a": "integer"})
|
|
36
|
+
|
|
37
|
+
update_data = pd.DataFrame({"a": np.array([5, 6, 7, 8], dtype="int64")})
|
|
38
|
+
|
|
39
|
+
tbl.update(update_data)
|
|
40
|
+
|
|
41
|
+
assert tbl.view().to_columns() == {"a": [5, 6, 7, 8]}
|
|
42
|
+
|
|
43
|
+
def test_update_df_bool(self):
|
|
44
|
+
tbl = Table({"a": [True, False, True, False]})
|
|
45
|
+
|
|
46
|
+
update_data = pd.DataFrame({"a": [True, False, True, False]})
|
|
47
|
+
|
|
48
|
+
tbl.update(update_data)
|
|
49
|
+
|
|
50
|
+
assert tbl.view().to_columns() == {
|
|
51
|
+
"a": [True, False, True, False, True, False, True, False]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
def test_update_df_str(self):
|
|
55
|
+
tbl = Table({"a": ["a", "b", "c", "d"]})
|
|
56
|
+
|
|
57
|
+
update_data = pd.DataFrame({"a": ["a", "b", "c", "d"]})
|
|
58
|
+
|
|
59
|
+
tbl.update(update_data)
|
|
60
|
+
|
|
61
|
+
assert tbl.view().to_columns() == {
|
|
62
|
+
"a": ["a", "b", "c", "d", "a", "b", "c", "d"]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
def test_update_df_date(self, util):
|
|
66
|
+
# set_global_serializer(serializer)
|
|
67
|
+
tbl = Table({"a": [date(2019, 7, 11)]})
|
|
68
|
+
|
|
69
|
+
assert tbl.schema() == {"a": "date"}
|
|
70
|
+
|
|
71
|
+
update_data = pd.DataFrame({"a": [date(2019, 7, 12)]})
|
|
72
|
+
|
|
73
|
+
tbl.update(update_data)
|
|
74
|
+
assert tbl.view().to_columns() == {
|
|
75
|
+
"a": [
|
|
76
|
+
util.to_timestamp(d)
|
|
77
|
+
for d in [datetime(2019, 7, 11), datetime(2019, 7, 12)]
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@mark.skip(reason="this test relies on a lossy conversion from datetime -> date.")
|
|
82
|
+
def test_update_df_date_timestamp(self, util):
|
|
83
|
+
tbl = Table({"a": [date(2019, 7, 11)]})
|
|
84
|
+
|
|
85
|
+
assert tbl.schema() == {"a": "date"}
|
|
86
|
+
|
|
87
|
+
update_data = pd.DataFrame({"a": [datetime(2019, 7, 12, 0, 0, 0)]})
|
|
88
|
+
|
|
89
|
+
tbl.update(update_data)
|
|
90
|
+
assert tbl.view().to_columns() == {
|
|
91
|
+
"a": [
|
|
92
|
+
util.to_timestamp(datetime(2019, 7, 11)),
|
|
93
|
+
util.to_timestamp(datetime(2019, 7, 12)),
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
def test_update_df_datetime(self, util):
|
|
98
|
+
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
99
|
+
|
|
100
|
+
update_data = pd.DataFrame({"a": [datetime(2019, 7, 12, 11, 0)]})
|
|
101
|
+
|
|
102
|
+
tbl.update(update_data)
|
|
103
|
+
assert tbl.view().to_columns() == {
|
|
104
|
+
"a": [
|
|
105
|
+
util.to_timestamp(datetime(2019, 7, 11, 11, 0)),
|
|
106
|
+
util.to_timestamp(datetime(2019, 7, 12, 11, 0)),
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
def test_update_df_datetime_timestamp_seconds(self, util):
|
|
111
|
+
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
112
|
+
|
|
113
|
+
update_data = pd.DataFrame({"a": [datetime(2019, 7, 12, 11, 0)]})
|
|
114
|
+
|
|
115
|
+
tbl.update(update_data)
|
|
116
|
+
assert tbl.view().to_columns() == {
|
|
117
|
+
"a": [
|
|
118
|
+
util.to_timestamp(datetime(2019, 7, 11, 11, 0)),
|
|
119
|
+
util.to_timestamp(datetime(2019, 7, 12, 11, 0)),
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
def test_update_df_datetime_timestamp_ms(self, util):
|
|
124
|
+
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)]})
|
|
125
|
+
|
|
126
|
+
update_data = pd.DataFrame({"a": [datetime(2019, 7, 12, 11, 0)]})
|
|
127
|
+
|
|
128
|
+
tbl.update(update_data)
|
|
129
|
+
assert tbl.view().to_columns() == {
|
|
130
|
+
"a": [
|
|
131
|
+
util.to_timestamp(datetime(2019, 7, 11, 11, 0)),
|
|
132
|
+
util.to_timestamp(datetime(2019, 7, 12, 11, 0)),
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
def test_update_df_partial(self):
|
|
137
|
+
tbl = Table({"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"]}, index="b")
|
|
138
|
+
|
|
139
|
+
update_data = pd.DataFrame({"a": [5, 6, 7, 8], "b": ["a", "b", "c", "d"]})
|
|
140
|
+
|
|
141
|
+
tbl.update(update_data)
|
|
142
|
+
|
|
143
|
+
assert tbl.view().to_columns() == {"a": [5, 6, 7, 8], "b": ["a", "b", "c", "d"]}
|
|
144
|
+
|
|
145
|
+
def test_df_update_index(self):
|
|
146
|
+
tbl = Table(pd.DataFrame({"a": [1, 2, 3, 4]}))
|
|
147
|
+
update_data = pd.DataFrame({"a": [5, 6, 7, 8], "__INDEX__": [0, 1, 2, 3]})
|
|
148
|
+
tbl.update(update_data)
|
|
149
|
+
assert tbl.view().to_columns() == {"a": [5, 6, 7, 8], "index": [0, 1, 2, 3]}
|
|
150
|
+
|
|
151
|
+
def test_update_df_partial_implicit(self):
|
|
152
|
+
tbl = Table({"a": [1, 2, 3, 4]})
|
|
153
|
+
|
|
154
|
+
update_data = pd.DataFrame({"a": [5, 6, 7, 8], "__INDEX__": [0, 1, 2, 3]})
|
|
155
|
+
|
|
156
|
+
tbl.update(update_data)
|
|
157
|
+
|
|
158
|
+
assert tbl.view().to_columns() == {"a": [5, 6, 7, 8]}
|
|
159
|
+
|
|
160
|
+
def test_update_df_datetime_partial(self, util):
|
|
161
|
+
tbl = Table({"a": [datetime(2019, 7, 11, 11, 0)], "b": [1]}, index="b")
|
|
162
|
+
|
|
163
|
+
update_data = pd.DataFrame({"a": [datetime(2019, 7, 12, 11, 0)], "b": [1]})
|
|
164
|
+
|
|
165
|
+
tbl.update(update_data)
|
|
166
|
+
|
|
167
|
+
assert tbl.view().to_columns() == {
|
|
168
|
+
"a": [util.to_timestamp(datetime(2019, 7, 12, 11, 0))],
|
|
169
|
+
"b": [1],
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
def test_update_df_one_col(self):
|
|
173
|
+
tbl = Table({"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"]})
|
|
174
|
+
update_data = pd.DataFrame({"a": [5, 6, 7]})
|
|
175
|
+
tbl.update(update_data)
|
|
176
|
+
assert tbl.view().to_columns() == {
|
|
177
|
+
"a": [1, 2, 3, 4, 5, 6, 7],
|
|
178
|
+
"b": ["a", "b", "c", "d", None, None, None],
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
def test_update_df_nonseq_partial(self):
|
|
182
|
+
tbl = Table({"a": [1, 2, 3, 4], "b": ["a", "b", "c", "d"]}, index="b")
|
|
183
|
+
update_data = pd.DataFrame({"a": [5, 6, 7], "b": ["a", "c", "d"]})
|
|
184
|
+
tbl.update(update_data)
|
|
185
|
+
assert tbl.view().to_columns() == {"a": [5, 2, 6, 7], "b": ["a", "b", "c", "d"]}
|
|
186
|
+
|
|
187
|
+
@pytest.mark.skip
|
|
188
|
+
def test_update_df_with_none_partial(self):
|
|
189
|
+
tbl = Table({"a": [1, float("nan"), 3], "b": ["a", None, "d"]}, index="b")
|
|
190
|
+
update_data = pd.DataFrame({"a": [4, 5], "b": ["a", "d"]})
|
|
191
|
+
tbl.update(update_data)
|
|
192
|
+
assert tbl.view().to_columns() == {
|
|
193
|
+
"a": [None, 4, 5],
|
|
194
|
+
"b": [None, "a", "d"],
|
|
195
|
+
} # pkeys are ordered
|
|
196
|
+
|
|
197
|
+
def test_update_df_unset_partial(self):
|
|
198
|
+
tbl = Table({"a": [1, 2, 3], "b": ["a", "b", "c"]}, index="b")
|
|
199
|
+
update_data = pd.DataFrame(
|
|
200
|
+
{"a": pd.Series([None, None], dtype=pd.Int32Dtype()), "b": ["a", "c"]}
|
|
201
|
+
)
|
|
202
|
+
tbl.update(update_data)
|
|
203
|
+
assert tbl.view().to_columns() == {"a": [None, 2, None], "b": ["a", "b", "c"]}
|
|
204
|
+
|
|
205
|
+
def test_update_df_nan_partial(self):
|
|
206
|
+
tbl = Table({"a": [1, 2, 3], "b": ["a", "b", "c"]}, index="b")
|
|
207
|
+
update_data = pd.DataFrame(
|
|
208
|
+
{"a": pd.Series([None, None], dtype=pd.Int32Dtype()), "b": ["a", "c"]}
|
|
209
|
+
)
|
|
210
|
+
tbl.update(update_data)
|
|
211
|
+
assert tbl.view().to_columns() == {"a": [None, 2, None], "b": ["a", "b", "c"]}
|