perspective-python 3.0.0rc1__cp39-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.
Files changed (70) hide show
  1. perspective/__init__.py +78 -0
  2. perspective/extension/finos-perspective-nbextension.json +5 -0
  3. perspective/handlers/__init__.py +26 -0
  4. perspective/handlers/aiohttp.py +54 -0
  5. perspective/handlers/starlette.py +51 -0
  6. perspective/handlers/tornado.py +61 -0
  7. perspective/perspective.pyd +0 -0
  8. perspective/templates/exported_widget.html.jinja +35 -0
  9. perspective/tests/__init__.py +11 -0
  10. perspective/tests/conftest.py +268 -0
  11. perspective/tests/core/__init__.py +11 -0
  12. perspective/tests/core/test_async.py +436 -0
  13. perspective/tests/core/test_threadpool.py +48 -0
  14. perspective/tests/server/__init__.py +11 -0
  15. perspective/tests/server/test_server.py +1062 -0
  16. perspective/tests/server/test_session.py +55 -0
  17. perspective/tests/single_threaded/test_single_threaded.py +61 -0
  18. perspective/tests/table/__init__.py +11 -0
  19. perspective/tests/table/arrow/date32.arrow +0 -0
  20. perspective/tests/table/arrow/date64.arrow +0 -0
  21. perspective/tests/table/arrow/dict.arrow +0 -0
  22. perspective/tests/table/arrow/dict_update.arrow +0 -0
  23. perspective/tests/table/arrow/int_float_str.arrow +0 -0
  24. perspective/tests/table/arrow/int_float_str_file.arrow +0 -0
  25. perspective/tests/table/arrow/int_float_str_update.arrow +0 -0
  26. perspective/tests/table/object_sequence.py +402 -0
  27. perspective/tests/table/test_delete.py +124 -0
  28. perspective/tests/table/test_exception.py +53 -0
  29. perspective/tests/table/test_leaks.py +54 -0
  30. perspective/tests/table/test_ports.py +178 -0
  31. perspective/tests/table/test_remove.py +102 -0
  32. perspective/tests/table/test_table.py +610 -0
  33. perspective/tests/table/test_table_arrow.py +452 -0
  34. perspective/tests/table/test_table_datetime.py +2409 -0
  35. perspective/tests/table/test_table_infer.py +201 -0
  36. perspective/tests/table/test_table_limit.py +43 -0
  37. perspective/tests/table/test_table_numpy.py +1022 -0
  38. perspective/tests/table/test_table_pandas.py +1018 -0
  39. perspective/tests/table/test_to_arrow.py +414 -0
  40. perspective/tests/table/test_to_arrow_lz4.py +33 -0
  41. perspective/tests/table/test_to_format.py +1024 -0
  42. perspective/tests/table/test_update.py +545 -0
  43. perspective/tests/table/test_update_arrow.py +980 -0
  44. perspective/tests/table/test_update_numpy.py +252 -0
  45. perspective/tests/table/test_update_pandas.py +211 -0
  46. perspective/tests/table/test_view.py +2235 -0
  47. perspective/tests/table/test_view_expression.py +1940 -0
  48. perspective/tests/viewer/__init__.py +11 -0
  49. perspective/tests/viewer/test_validate.py +70 -0
  50. perspective/tests/viewer/test_viewer.py +245 -0
  51. perspective/tests/widget/__init__.py +11 -0
  52. perspective/tests/widget/test_widget.py +278 -0
  53. perspective/tests/widget/test_widget_pandas.py +453 -0
  54. perspective/viewer/__init__.py +15 -0
  55. perspective/viewer/validate.py +22 -0
  56. perspective/viewer/viewer.py +331 -0
  57. perspective/viewer/viewer_traitlets.py +101 -0
  58. perspective/widget/__init__.py +16 -0
  59. perspective/widget/widget.py +269 -0
  60. perspective.data/data/share/jupyter/labextensions/@finos/perspective-jupyterlab/install.json +5 -0
  61. perspective.data/data/share/jupyter/labextensions/@finos/perspective-jupyterlab/package.json +81 -0
  62. perspective.data/data/share/jupyter/labextensions/@finos/perspective-jupyterlab/static/253.6f17b87bb4eb1e656365.js +18 -0
  63. perspective.data/data/share/jupyter/labextensions/@finos/perspective-jupyterlab/static/253.6f17b87bb4eb1e656365.js.LICENSE.txt +59 -0
  64. perspective.data/data/share/jupyter/labextensions/@finos/perspective-jupyterlab/static/905.d3bbc3d5954582d507bb.js +1 -0
  65. perspective.data/data/share/jupyter/labextensions/@finos/perspective-jupyterlab/static/remoteEntry.7044010cbbf2a7208035.js +1 -0
  66. perspective.data/data/share/jupyter/labextensions/@finos/perspective-jupyterlab/static/style.js +4 -0
  67. perspective.data/data/share/jupyter/labextensions/@finos/perspective-jupyterlab/static/third-party-licenses.json +16 -0
  68. perspective_python-3.0.0rc1.dist-info/METADATA +13 -0
  69. perspective_python-3.0.0rc1.dist-info/RECORD +70 -0
  70. perspective_python-3.0.0rc1.dist-info/WHEEL +4 -0
@@ -0,0 +1,414 @@
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 pyarrow as pa
14
+ from datetime import date, datetime
15
+ import perspective as psp
16
+
17
+ client = psp.Server().new_local_client()
18
+ Table = client.table
19
+
20
+
21
+ class TestToArrow(object):
22
+ def test_to_arrow_nones_symmetric(self):
23
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
24
+ tbl = Table(data)
25
+ assert tbl.schema() == {"a": "integer", "b": "float"}
26
+ arr = tbl.view().to_arrow()
27
+ tbl2 = Table(arr)
28
+ assert tbl2.view().to_columns() == data
29
+
30
+ def test_to_arrow_big_numbers_symmetric(self):
31
+ data = {
32
+ "a": [1, 2, 3, 4],
33
+ "b": [
34
+ 1.7976931348623157e308,
35
+ 1.7976931348623157e308,
36
+ 1.7976931348623157e308,
37
+ 1.7976931348623157e308,
38
+ ],
39
+ }
40
+ tbl = Table(data)
41
+ assert tbl.schema() == {"a": "integer", "b": "float"}
42
+ arr = tbl.view().to_arrow()
43
+ tbl2 = Table(arr)
44
+ assert tbl2.view().to_columns() == data
45
+
46
+ def test_to_arrow_boolean_symmetric(self):
47
+ data = {"a": [True, False, None, False, True, None]}
48
+ tbl = Table(data)
49
+ assert tbl.schema() == {"a": "boolean"}
50
+ arr = tbl.view().to_arrow()
51
+ tbl2 = Table(arr)
52
+ assert tbl2.view().to_columns() == data
53
+
54
+ def test_to_arrow_str_symmetric(self):
55
+ data = {"a": ["a", "b", "c", "d", "e", None]}
56
+ tbl = Table(data)
57
+ assert tbl.schema() == {"a": "string"}
58
+ arr = tbl.view().to_arrow()
59
+ tbl2 = Table(arr)
60
+ assert tbl2.view().to_columns() == data
61
+
62
+ def test_to_arrow_str_dict(self):
63
+ data = {
64
+ "a": ["abcdefg", "abcdefg", "h"],
65
+ "b": ["aaa", "bbb", "bbb"],
66
+ "c": ["hello", "world", "world"],
67
+ }
68
+ tbl = Table(data)
69
+ assert tbl.schema() == {"a": "string", "b": "string", "c": "string"}
70
+ arr = tbl.view().to_arrow()
71
+
72
+ # assert that we are actually generating dict arrays
73
+ buf = pa.BufferReader(arr)
74
+ reader = pa.ipc.open_stream(buf)
75
+ arrow_table = reader.read_all()
76
+ arrow_schema = arrow_table.schema
77
+
78
+ for name in ("a", "b", "c"):
79
+ arrow_type = arrow_schema.field(name).type
80
+ assert pa.types.is_dictionary(arrow_type)
81
+
82
+ # assert that data is symmetrical
83
+ tbl2 = Table(arr)
84
+ assert tbl2.view().to_columns() == data
85
+
86
+ def test_to_arrow_date_symmetric(self):
87
+ # data = {"a": [date(2019, 7, 11), date(2016, 2, 29), date(2019, 12, 10)]}
88
+ # tbl = Table(data)
89
+ tbl = Table({"a": "date"})
90
+ # data = {"a": map(lambda x: x.getTime(), [date(2019, 7, 11), date(2016, 2, 29), date(2019, 12, 10)])}
91
+ data = {"a": [date(2019, 7, 11), date(2016, 2, 29), date(2019, 12, 10)]}
92
+ tbl.update(data)
93
+ assert tbl.schema() == {"a": "date"}
94
+ arr = tbl.view().to_arrow()
95
+ tbl2 = Table(arr)
96
+ ts = lambda x: int(datetime.timestamp(x) * 1000)
97
+ assert tbl2.schema() == tbl.schema()
98
+ assert tbl2.view().to_columns() == {
99
+ "a": [
100
+ ts(datetime(2019, 7, 11)),
101
+ ts(datetime(2016, 2, 29)),
102
+ ts(datetime(2019, 12, 10)),
103
+ ]
104
+ }
105
+
106
+ def test_to_arrow_date_symmetric_january(self, util):
107
+ data = {"a": [date(2019, 1, 1), date(2016, 1, 1), date(2019, 1, 1)]}
108
+ tbl = Table(data)
109
+ assert tbl.schema() == {"a": "date"}
110
+ arr = tbl.view().to_arrow()
111
+ tbl2 = Table(arr)
112
+ assert tbl2.schema() == tbl.schema()
113
+ assert tbl2.view().to_columns() == {
114
+ "a": [
115
+ util.to_timestamp(x)
116
+ for x in [
117
+ datetime(2019, 1, 1),
118
+ datetime(2016, 1, 1),
119
+ datetime(2019, 1, 1),
120
+ ]
121
+ ]
122
+ }
123
+
124
+ def test_to_arrow_datetime_symmetric(self, util):
125
+ data = {
126
+ "a": [
127
+ datetime(2019, 7, 11, 12, 30),
128
+ datetime(2016, 2, 29, 11, 0),
129
+ datetime(2019, 12, 10, 12, 0),
130
+ ]
131
+ }
132
+ tbl = Table(data)
133
+ assert tbl.schema() == {"a": "datetime"}
134
+ arr = tbl.view().to_arrow()
135
+ tbl2 = Table(arr)
136
+ assert tbl2.schema() == tbl.schema()
137
+ assert tbl2.view().to_columns() == {
138
+ "a": [
139
+ util.to_timestamp(x)
140
+ for x in [
141
+ datetime(2019, 7, 11, 12, 30),
142
+ datetime(2016, 2, 29, 11, 0),
143
+ datetime(2019, 12, 10, 12, 0),
144
+ ]
145
+ ]
146
+ }
147
+
148
+ def test_to_arrow_one_symmetric(self):
149
+ data = {
150
+ "a": [1, 2, 3, 4],
151
+ "b": ["a", "b", "c", "d"],
152
+ "c": [
153
+ datetime(2019, 7, 11, 12, 0),
154
+ datetime(2019, 7, 11, 12, 10),
155
+ datetime(2019, 7, 11, 12, 20),
156
+ datetime(2019, 7, 11, 12, 30),
157
+ ],
158
+ }
159
+ tbl = Table(data)
160
+ view = tbl.view(group_by=["a"])
161
+ arrow = view.to_arrow()
162
+ tbl2 = Table(arrow)
163
+ assert tbl2.schema() == {
164
+ "a (Group by 1)": "integer",
165
+ "a": "integer",
166
+ "b": "integer",
167
+ "c": "integer",
168
+ }
169
+ d = view.to_columns()
170
+ d["a (Group by 1)"] = [
171
+ x[0] if len(x) > 0 else None for x in d.pop("__ROW_PATH__")
172
+ ]
173
+ assert tbl2.view().to_columns() == d
174
+
175
+ def test_to_arrow_two_symmetric(self):
176
+ data = {
177
+ "a": [1, 2, 3, 4],
178
+ "b": ["hello", "world", "hello2", "world2"],
179
+ "c": [datetime(2019, 7, 11, 12, i) for i in range(0, 40, 10)],
180
+ }
181
+ tbl = Table(data)
182
+ view = tbl.view(group_by=["a"], split_by=["b"])
183
+ arrow = view.to_arrow()
184
+ tbl2 = Table(arrow)
185
+ assert tbl2.schema() == {
186
+ "a (Group by 1)": "integer",
187
+ "hello|a": "integer",
188
+ "hello|b": "integer",
189
+ "hello|c": "integer",
190
+ "world|a": "integer",
191
+ "world|b": "integer",
192
+ "world|c": "integer",
193
+ "hello2|a": "integer",
194
+ "hello2|b": "integer",
195
+ "hello2|c": "integer",
196
+ "world2|a": "integer",
197
+ "world2|b": "integer",
198
+ "world2|c": "integer",
199
+ }
200
+ d = view.to_columns()
201
+ d["a (Group by 1)"] = [
202
+ x[0] if len(x) > 0 else None for x in d.pop("__ROW_PATH__")
203
+ ]
204
+ assert tbl2.view().to_columns() == d
205
+
206
+ def test_to_arrow_column_only_symmetric(self):
207
+ data = {
208
+ "a": [1, 2, 3, 4],
209
+ "b": ["a", "b", "c", "d"],
210
+ "c": [datetime(2019, 7, 11, 12, i) for i in range(0, 40, 10)],
211
+ }
212
+ tbl = Table(data)
213
+ view = tbl.view(split_by=["a"])
214
+ arrow = view.to_arrow()
215
+ tbl2 = Table(arrow)
216
+ assert tbl2.schema() == {
217
+ "1|a": "integer",
218
+ "1|b": "string",
219
+ "1|c": "datetime",
220
+ "2|a": "integer",
221
+ "2|b": "string",
222
+ "2|c": "datetime",
223
+ "3|a": "integer",
224
+ "3|b": "string",
225
+ "3|c": "datetime",
226
+ "4|a": "integer",
227
+ "4|b": "string",
228
+ "4|c": "datetime",
229
+ }
230
+ d = view.to_columns()
231
+ assert tbl2.view().to_columns() == d
232
+
233
+ # start and end row
234
+ def test_to_arrow_start_row(self):
235
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
236
+ tbl = Table(data)
237
+ assert tbl.schema() == {"a": "integer", "b": "float"}
238
+ arr = tbl.view().to_arrow(start_row=3)
239
+ tbl2 = Table(arr)
240
+ assert tbl2.view().to_columns() == {"a": data["a"][3:], "b": data["b"][3:]}
241
+
242
+ def test_to_arrow_end_row(self):
243
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
244
+ tbl = Table(data)
245
+ assert tbl.schema() == {"a": "integer", "b": "float"}
246
+ arr = tbl.view().to_arrow(end_row=2)
247
+ tbl2 = Table(arr)
248
+ assert tbl2.view().to_columns() == {"a": data["a"][:2], "b": data["b"][:2]}
249
+
250
+ def test_to_arrow_start_end_row(self):
251
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
252
+ tbl = Table(data)
253
+ assert tbl.schema() == {"a": "integer", "b": "float"}
254
+ arr = tbl.view().to_arrow(start_row=2, end_row=3)
255
+ tbl2 = Table(arr)
256
+ assert tbl2.view().to_columns() == {"a": data["a"][2:3], "b": data["b"][2:3]}
257
+
258
+ def test_to_arrow_start_end_row_equiv(self):
259
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
260
+ tbl = Table(data)
261
+ assert tbl.schema() == {"a": "integer", "b": "float"}
262
+ arr = tbl.view().to_arrow(start_row=2, end_row=2)
263
+ tbl2 = Table(arr)
264
+ assert tbl2.view().to_columns() == {"a": [], "b": []}
265
+
266
+ def test_to_arrow_start_row_invalid(self):
267
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
268
+ tbl = Table(data)
269
+ assert tbl.schema() == {"a": "integer", "b": "float"}
270
+ arr = tbl.view().to_arrow(start_row=-1)
271
+ tbl2 = Table(arr)
272
+ assert tbl2.view().to_columns() == data
273
+
274
+ def test_to_arrow_end_row_invalid(self):
275
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
276
+ tbl = Table(data)
277
+ assert tbl.schema() == {"a": "integer", "b": "float"}
278
+ arr = tbl.view().to_arrow(end_row=6)
279
+ tbl2 = Table(arr)
280
+ assert tbl2.view().to_columns() == data
281
+
282
+ def test_to_arrow_start_end_row_invalid(self):
283
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
284
+ tbl = Table(data)
285
+ assert tbl.schema() == {"a": "integer", "b": "float"}
286
+ arr = tbl.view().to_arrow(start_row=-1, end_row=6)
287
+ tbl2 = Table(arr)
288
+ assert tbl2.view().to_columns() == data
289
+
290
+ def test_to_arrow_start_col(self):
291
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
292
+ tbl = Table(data)
293
+ assert tbl.schema() == {"a": "integer", "b": "float"}
294
+ arr = tbl.view().to_arrow(start_col=1)
295
+ tbl2 = Table(arr)
296
+ assert tbl2.view().to_columns() == {"b": data["b"]}
297
+
298
+ def test_to_arrow_end_col(self):
299
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
300
+ tbl = Table(data)
301
+ assert tbl.schema() == {"a": "integer", "b": "float"}
302
+ arr = tbl.view().to_arrow(end_col=1)
303
+ tbl2 = Table(arr)
304
+ assert tbl2.view().to_columns() == {"a": data["a"]}
305
+
306
+ def test_to_arrow_start_end_col(self):
307
+ data = {
308
+ "a": [None, 1, None, 2, 3],
309
+ "b": [1.5, 2.5, None, 3.5, None],
310
+ "c": [None, 1, None, 2, 3],
311
+ "d": [1.5, 2.5, None, 3.5, None],
312
+ }
313
+ tbl = Table(data)
314
+ assert tbl.schema() == {
315
+ "a": "integer",
316
+ "b": "float",
317
+ "c": "integer",
318
+ "d": "float",
319
+ }
320
+ arr = tbl.view().to_arrow(start_col=1, end_col=3)
321
+ tbl2 = Table(arr)
322
+ assert tbl2.view().to_columns() == {"b": data["b"], "c": data["c"]}
323
+
324
+ def test_to_arrow_start_col_invalid(self):
325
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
326
+ tbl = Table(data)
327
+ assert tbl.schema() == {"a": "integer", "b": "float"}
328
+ arr = tbl.view().to_arrow(start_col=-1)
329
+ tbl2 = Table(arr)
330
+ assert tbl2.view().to_columns() == data
331
+
332
+ def test_to_arrow_end_col_invalid(self):
333
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
334
+ tbl = Table(data)
335
+ assert tbl.schema() == {"a": "integer", "b": "float"}
336
+ arr = tbl.view().to_arrow(end_col=6)
337
+ tbl2 = Table(arr)
338
+ assert tbl2.view().to_columns() == data
339
+
340
+ def test_to_arrow_start_end_col_invalid(self):
341
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
342
+ tbl = Table(data)
343
+ assert tbl.schema() == {"a": "integer", "b": "float"}
344
+ arr = tbl.view().to_arrow(start_col=-1, end_col=6)
345
+ tbl2 = Table(arr)
346
+ assert tbl2.view().to_columns() == data
347
+
348
+ def test_to_arrow_start_end_col_equiv_row(self):
349
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
350
+ tbl = Table(data)
351
+ assert tbl.schema() == {"a": "integer", "b": "float"}
352
+ arr = tbl.view().to_arrow(start_col=1, end_col=1, start_row=2, end_row=3)
353
+ tbl2 = Table(arr)
354
+ # start/end col is a range - thus start=end provides no columns
355
+ assert tbl2.view().to_columns() == {}
356
+
357
+ def test_to_arrow_start_end_col_equiv(self):
358
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
359
+ tbl = Table(data)
360
+ assert tbl.schema() == {"a": "integer", "b": "float"}
361
+ arr = tbl.view().to_arrow(start_col=1, end_col=1)
362
+ tbl2 = Table(arr)
363
+ assert tbl2.view().to_columns() == {}
364
+
365
+ def test_to_arrow_start_end_row_end_col(self):
366
+ data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
367
+ tbl = Table(data)
368
+ assert tbl.schema() == {"a": "integer", "b": "float"}
369
+ arr = tbl.view().to_arrow(end_col=1, start_row=2, end_row=3)
370
+ tbl2 = Table(arr)
371
+ assert tbl2.view().to_columns() == tbl.view().to_columns(
372
+ end_col=1, start_row=2, end_row=3
373
+ )
374
+
375
+ def test_to_arrow_start_end_col_start_row(self):
376
+ data = {
377
+ "a": [None, 1, None, 2, 3],
378
+ "b": [1.5, 2.5, None, 3.5, None],
379
+ "c": [1.5, 2.5, None, 4.5, None],
380
+ }
381
+ tbl = Table(data)
382
+ assert tbl.schema() == {"a": "integer", "b": "float", "c": "float"}
383
+ arr = tbl.view().to_arrow(start_col=1, end_col=2, start_row=2)
384
+ tbl2 = Table(arr)
385
+ assert tbl2.view().to_columns() == tbl.view().to_columns(
386
+ start_col=1, end_col=2, start_row=2
387
+ )
388
+
389
+ def test_to_arrow_start_end_col_end_row(self):
390
+ data = {
391
+ "a": [None, 1, None, 2, 3],
392
+ "b": [1.5, 2.5, None, 3.5, None],
393
+ "c": [1.5, 2.5, None, 4.5, None],
394
+ }
395
+ tbl = Table(data)
396
+ assert tbl.schema() == {"a": "integer", "b": "float", "c": "float"}
397
+ arr = tbl.view().to_arrow(start_col=1, end_col=2, end_row=2)
398
+ tbl2 = Table(arr)
399
+ assert tbl2.view().to_columns() == tbl.view().to_columns(
400
+ start_col=1, end_col=2, end_row=2
401
+ )
402
+
403
+ def test_to_arrow_one_mean(self):
404
+ data = {"a": [1, 2, 3, 4], "b": ["a", "a", "b", "b"]}
405
+
406
+ table = Table(data)
407
+ view = table.view(group_by=["b"], columns=["a"], aggregates={"a": "mean"})
408
+ arrow = view.to_arrow()
409
+
410
+ table2 = Table(arrow)
411
+ view2 = table2.view()
412
+ result = view2.to_columns()
413
+
414
+ assert result == {"b (Group by 1)": [None, "a", "b"], "a": [2.5, 1.5, 3.5]}
@@ -0,0 +1,33 @@
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 os
14
+ import perspective as psp
15
+
16
+ client = psp.Server().new_local_client()
17
+ Table = client.table
18
+
19
+
20
+ class TestToArrowLZ4(object):
21
+ def test_to_arrow_lz4_roundtrip(self, superstore):
22
+ original_tbl = Table(superstore.to_dict(orient="records"))
23
+ arrow_uncompressed = original_tbl.view().to_arrow(compression=None)
24
+
25
+ tbl = Table(arrow_uncompressed)
26
+ arr = tbl.view().to_arrow(compression="lz4")
27
+ assert len(arr) < len(arrow_uncompressed)
28
+ tbl2 = Table(arr)
29
+ arr2 = tbl2.view().to_arrow(compression=None)
30
+ assert len(arr2) > len(arr)
31
+ tbl3 = Table(arr)
32
+ arr3 = tbl3.view().to_arrow(compression="lz4")
33
+ assert len(arr3) == len(arr)