|
1 |
| - |
2 |
| -# Create sentinal Undefined object |
3 |
| -from traitlets import Undefined |
4 | 1 | import numpy as np
|
5 | 2 |
|
| 3 | +from plotly.basedatatypes import Undefined |
| 4 | + |
| 5 | + |
6 | 6 | def _py_to_js(v, widget_manager):
|
7 |
| - # print('_py_to_js') |
8 |
| - # print(v) |
| 7 | + """ |
| 8 | + Python -> Javascript ipywidget serializer |
| 9 | +
|
| 10 | + This function must repalce all objects that the ipywidget library |
| 11 | + can't serialize natively (e.g. numpy arrays) with serializable |
| 12 | + representations |
| 13 | +
|
| 14 | + Parameters |
| 15 | + ---------- |
| 16 | + v |
| 17 | + Object to be serialized |
| 18 | + widget_manager |
| 19 | + ipywidget widget_manager (unused) |
| 20 | +
|
| 21 | + Returns |
| 22 | + ------- |
| 23 | + any |
| 24 | + Value that the ipywidget library can serialize natively |
| 25 | + """ |
| 26 | + |
| 27 | + # Handle dict recursively |
| 28 | + # ----------------------- |
9 | 29 | if isinstance(v, dict):
|
10 | 30 | return {k: _py_to_js(v, widget_manager) for k, v in v.items()}
|
| 31 | + |
| 32 | + # Handle list/tuple recursively |
| 33 | + # ----------------------------- |
11 | 34 | elif isinstance(v, (list, tuple)):
|
12 | 35 | return [_py_to_js(v, widget_manager) for v in v]
|
| 36 | + |
| 37 | + # Handle numpy array |
| 38 | + # ------------------ |
13 | 39 | elif isinstance(v, np.ndarray):
|
14 |
| - if v.ndim == 1 and v.dtype.kind in ['u', 'i', 'f']: # (un)signed integer or float |
15 |
| - return {'buffer': memoryview(v), 'dtype': str(v.dtype), 'shape': v.shape} |
| 40 | + # Convert 1D numpy arrays with numeric types to memoryviews with |
| 41 | + # datatype and shape metadata. |
| 42 | + if v.ndim == 1 and v.dtype.kind in ['u', 'i', 'f']: |
| 43 | + return {'buffer': memoryview(v), |
| 44 | + 'dtype': str(v.dtype), |
| 45 | + 'shape': v.shape} |
16 | 46 | else:
|
| 47 | + # Convert all other numpy to lists |
17 | 48 | return v.tolist()
|
| 49 | + |
| 50 | + # Handle Undefined |
| 51 | + # ---------------- |
| 52 | + if v is Undefined: |
| 53 | + return '_undefined_' |
| 54 | + |
| 55 | + # Handle simple value |
| 56 | + # ------------------- |
18 | 57 | else:
|
19 |
| - if v is Undefined: |
20 |
| - return '_undefined_' |
21 |
| - else: |
22 |
| - return v |
| 58 | + return v |
23 | 59 |
|
24 | 60 |
|
25 | 61 | def _js_to_py(v, widget_manager):
|
26 |
| - # print('_js_to_py') |
27 |
| - # print(v) |
| 62 | + """ |
| 63 | + Javascript -> Python ipywidget deserializer |
| 64 | +
|
| 65 | + Parameters |
| 66 | + ---------- |
| 67 | + v |
| 68 | + Object to be deserialized |
| 69 | + widget_manager |
| 70 | + ipywidget widget_manager (unused) |
| 71 | +
|
| 72 | + Returns |
| 73 | + ------- |
| 74 | + any |
| 75 | + Deserialized object for use by the Python side of the library |
| 76 | + """ |
| 77 | + # Handle dict |
| 78 | + # ----------- |
28 | 79 | if isinstance(v, dict):
|
29 | 80 | return {k: _js_to_py(v, widget_manager) for k, v in v.items()}
|
| 81 | + |
| 82 | + # Handle list/tuple |
| 83 | + # ----------------- |
30 | 84 | elif isinstance(v, (list, tuple)):
|
31 | 85 | return [_js_to_py(v, widget_manager) for v in v]
|
| 86 | + |
| 87 | + # Handle Undefined |
| 88 | + # ---------------- |
32 | 89 | elif isinstance(v, str) and v == '_undefined_':
|
33 | 90 | return Undefined
|
| 91 | + |
| 92 | + # Handle simple value |
| 93 | + # ------------------- |
34 | 94 | else:
|
35 | 95 | return v
|
36 | 96 |
|
37 | 97 |
|
| 98 | +# Custom serializer dict for use in ipywidget traitlet definitions |
38 | 99 | custom_serializers = {
|
39 | 100 | 'from_json': _js_to_py,
|
40 | 101 | 'to_json': _py_to_js
|
|
0 commit comments