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.
Files changed (79) hide show
  1. perspective/__init__.py +396 -0
  2. perspective/extension/finos-perspective-nbextension.json +5 -0
  3. perspective/handlers/__init__.py +11 -0
  4. perspective/handlers/aiohttp.py +61 -0
  5. perspective/handlers/starlette.py +55 -0
  6. perspective/handlers/tornado.py +184 -0
  7. perspective/perspective.pyd +0 -0
  8. perspective/templates/exported_widget.html.template +35 -0
  9. perspective/tests/__init__.py +11 -0
  10. perspective/tests/async/test_async_client.py +83 -0
  11. perspective/tests/async/test_websocket_client.py +124 -0
  12. perspective/tests/conftest.py +272 -0
  13. perspective/tests/core/__init__.py +11 -0
  14. perspective/tests/core/test_async.py +351 -0
  15. perspective/tests/multi_threaded/__init__.py +11 -0
  16. perspective/tests/multi_threaded/test_multi_threaded.py +201 -0
  17. perspective/tests/server/__init__.py +11 -0
  18. perspective/tests/server/test_server.py +1016 -0
  19. perspective/tests/server/test_session.py +110 -0
  20. perspective/tests/table/__init__.py +11 -0
  21. perspective/tests/table/arrow/date32.arrow +0 -0
  22. perspective/tests/table/arrow/date64.arrow +0 -0
  23. perspective/tests/table/arrow/dict.arrow +0 -0
  24. perspective/tests/table/arrow/dict_update.arrow +0 -0
  25. perspective/tests/table/arrow/int_float_str.arrow +0 -0
  26. perspective/tests/table/arrow/int_float_str_file.arrow +0 -0
  27. perspective/tests/table/arrow/int_float_str_update.arrow +0 -0
  28. perspective/tests/table/object_sequence.py +402 -0
  29. perspective/tests/table/test_column_paths.py +89 -0
  30. perspective/tests/table/test_delete.py +124 -0
  31. perspective/tests/table/test_exception.py +65 -0
  32. perspective/tests/table/test_leaks.py +54 -0
  33. perspective/tests/table/test_ports.py +178 -0
  34. perspective/tests/table/test_remove.py +102 -0
  35. perspective/tests/table/test_table.py +641 -0
  36. perspective/tests/table/test_table_arrow.py +503 -0
  37. perspective/tests/table/test_table_datetime.py +2409 -0
  38. perspective/tests/table/test_table_infer.py +201 -0
  39. perspective/tests/table/test_table_limit.py +45 -0
  40. perspective/tests/table/test_table_numpy.py +1022 -0
  41. perspective/tests/table/test_table_pandas.py +1018 -0
  42. perspective/tests/table/test_table_polars.py +251 -0
  43. perspective/tests/table/test_table_view_table.py +130 -0
  44. perspective/tests/table/test_to_arrow.py +417 -0
  45. perspective/tests/table/test_to_arrow_lz4.py +32 -0
  46. perspective/tests/table/test_to_format.py +1024 -0
  47. perspective/tests/table/test_to_polars.py +26 -0
  48. perspective/tests/table/test_update.py +545 -0
  49. perspective/tests/table/test_update_arrow.py +980 -0
  50. perspective/tests/table/test_update_pandas.py +211 -0
  51. perspective/tests/table/test_view.py +2261 -0
  52. perspective/tests/table/test_view_expression.py +1940 -0
  53. perspective/tests/test_dependencies.py +53 -0
  54. perspective/tests/viewer/__init__.py +11 -0
  55. perspective/tests/viewer/test_viewer.py +246 -0
  56. perspective/tests/widget/__init__.py +11 -0
  57. perspective/tests/widget/test_widget.py +278 -0
  58. perspective/tests/widget/test_widget_pandas.py +453 -0
  59. perspective/virtual_servers/__init__.py +134 -0
  60. perspective/virtual_servers/clickhouse.py +245 -0
  61. perspective/virtual_servers/duckdb.py +236 -0
  62. perspective/widget/__init__.py +349 -0
  63. perspective/widget/viewer/__init__.py +15 -0
  64. perspective/widget/viewer/validate.py +22 -0
  65. perspective/widget/viewer/viewer.py +343 -0
  66. perspective/widget/viewer/viewer_traitlets.py +101 -0
  67. perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/install.json +5 -0
  68. perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/package.json +71 -0
  69. perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/253.5f5c9e80605aa4106a28.js +2 -0
  70. perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/253.5f5c9e80605aa4106a28.js.LICENSE.txt +25 -0
  71. perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/523.c030af5d3c4f67ff83f6.js +1 -0
  72. perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/remoteEntry.95a8ea1b44d96032833f.js +1 -0
  73. perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/style.js +4 -0
  74. perspective_python-4.2.0.data/data/share/jupyter/labextensions/@perspective-dev/jupyterlab/static/third-party-licenses.json +16 -0
  75. perspective_python-4.2.0.dist-info/METADATA +27 -0
  76. perspective_python-4.2.0.dist-info/RECORD +79 -0
  77. perspective_python-4.2.0.dist-info/WHEEL +4 -0
  78. perspective_python-4.2.0.dist-info/licenses/LICENSE.md +193 -0
  79. perspective_python-4.2.0.dist-info/licenses/LICENSE_THIRDPARTY_cargo.yml +17395 -0
@@ -0,0 +1,201 @@
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
+ from datetime import date, datetime
14
+ from pytest import mark
15
+ import perspective as psp
16
+
17
+ client = psp.Server().new_local_client()
18
+ Table = client.table
19
+
20
+
21
+ class TestTableInfer(object):
22
+ def test_table_infer_int(self):
23
+ data = {"a": [None, None, None, None, 1, 0, 1, 1, 1]}
24
+ tbl = Table(data)
25
+ assert tbl.schema() == {"a": "integer"}
26
+
27
+ def test_table_infer_float(self):
28
+ data = {"a": [None, None, None, None, 1.0, 2.0]}
29
+ tbl = Table(data)
30
+ assert tbl.schema() == {"a": "float"}
31
+
32
+ def test_table_infer_bool(self):
33
+ bool_data = [{"a": True, "b": False}, {"a": True, "b": True}]
34
+ tbl = Table(bool_data)
35
+ assert tbl.size() == 2
36
+ assert tbl.schema() == {"a": "boolean", "b": "boolean"}
37
+
38
+ def test_table_infer_bool_str(self):
39
+ bool_data = [{"a": "True", "b": "False"}, {"a": "True", "b": "True"}]
40
+ tbl = Table(bool_data)
41
+ assert tbl.size() == 2
42
+ assert tbl.schema() == {"a": "boolean", "b": "boolean"}
43
+
44
+ @mark.skip(reason="Unsupported python specific behavior")
45
+ def test_table_bool_infer_str_all_formats_from_schema(self):
46
+ bool_data = [
47
+ {"a": "True", "b": "False"},
48
+ {"a": "t", "b": "f"},
49
+ {"a": "true", "b": "false"},
50
+ {"a": 1, "b": 0},
51
+ {"a": "on", "b": "off"},
52
+ ]
53
+ tbl = Table(bool_data)
54
+ assert tbl.schema() == {"a": "boolean", "b": "boolean"}
55
+ assert tbl.size() == 5
56
+ assert tbl.view().to_columns() == {
57
+ "a": [True, True, True, True, True],
58
+ "b": [False, False, False, False, False],
59
+ }
60
+
61
+ def test_table_infer_bool_variant(self):
62
+ data = {"a": [None, None, None, None, True, True, True]}
63
+ tbl = Table(data)
64
+ assert tbl.schema() == {"a": "boolean"}
65
+
66
+ def test_table_infer_str(self):
67
+ data = {"a": [None, None, None, None, None, None, "abc"]}
68
+ tbl = Table(data)
69
+ assert tbl.schema() == {"a": "string"}
70
+
71
+ @mark.skip(reason="Time is not a valid JSON type")
72
+ def test_table_infer_time_as_string(self):
73
+ # time objects are inferred as string
74
+ data = {
75
+ "a": [
76
+ None,
77
+ None,
78
+ None,
79
+ None,
80
+ None,
81
+ None,
82
+ datetime(2019, 7, 11, 12, 30, 5).time(),
83
+ ]
84
+ }
85
+ tbl = Table(data)
86
+ assert tbl.schema() == {"a": "string"}
87
+
88
+ @mark.skip(reason="Unsupported python specific behavior")
89
+ def test_table_infer_date_from_datetime(self):
90
+ # inferrence on non-pandas datasets defaults to datetime
91
+ data = {"a": [None, None, None, None, None, None, datetime(2019, 7, 11)]}
92
+ tbl = Table(data)
93
+ assert tbl.schema() == {"a": "datetime"}
94
+
95
+ def test_table_infer_date_from_date(self):
96
+ # pass in a `date` to make sure it infers as date
97
+ data = {"a": [None, None, None, None, None, None, date(2019, 7, 11)]}
98
+ tbl = Table(data)
99
+ assert tbl.schema() == {"a": "date"}
100
+
101
+ def test_table_infer_valid_date(self):
102
+ data = {"a": [None, None, None, None, None, None, "08/31/2019"]}
103
+ tbl = Table(data)
104
+ assert tbl.schema() == {"a": "date"}
105
+
106
+ def test_table_infer_ambiguous_date(self):
107
+ data = {"a": [None, None, None, None, None, None, "01/03/2019"]}
108
+ tbl = Table(data)
109
+ assert tbl.schema() == {"a": "date"}
110
+
111
+ def test_table_infer_ymd_date(self):
112
+ data = {"a": [None, None, None, None, None, None, "2019/01/03"]}
113
+ tbl = Table(data)
114
+ assert tbl.schema() == {"a": "date"}
115
+
116
+ def test_table_infer_invalid_date(self):
117
+ data = {"a": [None, None, None, None, None, None, "08/55/2019"]}
118
+ tbl = Table(data)
119
+ assert tbl.schema() == {"a": "string"}
120
+
121
+ def test_table_infer_date_edge(self):
122
+ data = {"a": [None, None, None, None, None, None, "08/31/2019 00:00:00"]}
123
+ tbl = Table(data)
124
+ assert tbl.schema() == {"a": "date"}
125
+
126
+ def test_table_infer_datetime_edge(self):
127
+ data = {"a": [None, None, None, None, None, None, "08/31/2019 00:00:01"]}
128
+ tbl = Table(data)
129
+ assert tbl.schema() == {"a": "datetime"}
130
+
131
+ def test_table_infer_valid_datetime(self):
132
+ data = {"a": [None, None, None, None, None, None, "08/31/2019 07:30:00"]}
133
+ tbl = Table(data)
134
+ assert tbl.schema() == {"a": "datetime"}
135
+
136
+ def test_table_infer_iso_datetime(self):
137
+ data = {"a": [None, None, None, None, None, None, "2019/07/25T09:00:00"]}
138
+ tbl = Table(data)
139
+ assert tbl.schema() == {"a": "datetime"}
140
+
141
+ def test_table_infer_datetime_separators(self):
142
+ data = {
143
+ "a": [
144
+ None,
145
+ None,
146
+ None,
147
+ None,
148
+ None,
149
+ "2019-07-25T09:00:00",
150
+ "2019/07/25T09:00:00",
151
+ ]
152
+ }
153
+ tbl = Table(data)
154
+ assert tbl.schema() == {"a": "datetime"}
155
+
156
+ def test_table_infer_datetime_tz(self):
157
+ data = {"a": [None, None, None, None, None, "2019-07-25T09:00:00-05:00"]}
158
+ tbl = Table(data)
159
+ assert tbl.schema() == {"a": "datetime"}
160
+
161
+ def test_table_infer_invalid_datetime(self):
162
+ data = {"a": [None, None, None, None, None, None, "08/31/2019 25:30:00"]}
163
+ tbl = Table(data)
164
+ assert tbl.schema() == {"a": "string"}
165
+
166
+ def test_table_infer_mixed_date(self):
167
+ data = {"a": [None, None, None, None, None, "08/11/2019"]}
168
+ tbl = Table(data)
169
+ assert tbl.schema() == {"a": "date"}
170
+
171
+ def test_table_infer_mixed_datetime(self):
172
+ data = {"a": [None, None, None, None, None, "08/11/2019 13:14:15"]}
173
+ tbl = Table(data)
174
+ assert tbl.schema() == {"a": "datetime"}
175
+
176
+ @mark.skip(reason="Numeric strings are not inferred as numbers")
177
+ def test_table_strict_datetime_infer(self):
178
+ data = {"a": ["10", "9", "8", "7", "6", "5", "4", "3", "2", "1"]}
179
+ tbl = Table(data)
180
+ assert tbl.schema() == {"a": "string"}
181
+
182
+ def test_table_strict_date_infer(self):
183
+ data = {"a": ["2019 09 10"]}
184
+ tbl = Table(data)
185
+ assert tbl.schema() == {"a": "date"}
186
+
187
+ def test_table_strict_datetime_separator_infer(self):
188
+ data = {"a": ["2019-10-01 7:30"]}
189
+ tbl = Table(data)
190
+ assert tbl.schema() == {"a": "datetime"}
191
+
192
+ def test_table_datetime_infer_no_false_positive(self):
193
+ data = {"a": [" . - / but clearly not a date"]}
194
+ tbl = Table(data)
195
+ assert tbl.schema() == {"a": "string"}
196
+
197
+ @mark.skip
198
+ def test_table_datetime_infer_from_string_with_time(self):
199
+ data = {"a": ["11:00 ABCD"]}
200
+ tbl = Table(data)
201
+ assert tbl.schema() == {"a": "string"}
@@ -0,0 +1,45 @@
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 perspective as psp
14
+
15
+ client = psp.Server().new_local_client()
16
+ Table = client.table
17
+
18
+
19
+ class TestTableInfer(object):
20
+ def test_table_limit_wraparound_does_not_respect_partial_none(self):
21
+ t = Table({"a": "float", "b": "float"}, limit=3)
22
+ t.update([{"a": 10}, {"b": 1}, {"a": 20}, {"a": None, "b": 2}])
23
+ d1 = t.view().to_json()
24
+
25
+ t2 = Table({"a": "float", "b": "float"}, limit=3)
26
+ t2.update([{"a": 10}, {"b": 1}, {"a": 20}, {"b": 2}])
27
+ d2 = t2.view().to_json()
28
+
29
+ assert d1[0] == d2[0]
30
+ assert d1[1:] == d2[1:]
31
+
32
+ def test_table_limit_wraparound_does_not_respect_partial(self):
33
+ t = Table({"a": "float", "b": "float"}, limit=3)
34
+ t.update([{"a": 10}, {"b": 1}, {"a": 20}, {"a": 10, "b": 2}])
35
+ d1 = t.view().to_columns()
36
+
37
+ t2 = Table({"a": "float", "b": "float"}, limit=3)
38
+ t2.update([{"a": 10}, {"b": 1}, {"a": 20}, {"b": 2}])
39
+ d2 = t2.view().to_columns()
40
+
41
+ assert d1 != d2
42
+
43
+ def test_table_limit_with_json(self):
44
+ t = Table({"a": [1, 2, 3]}, limit=1)
45
+ assert t.size() == 1