Skip to content

Commit c366931

Browse files
brichetpre-commit-ci[bot]martinRenou
authored
Add data without session corruption (#111)
* Add data without session corruption * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add a test on session when adding data * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Move function to glue_utils * Improving the readability of nested_compare Co-authored-by: martinRenou <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: martinRenou <[email protected]>
1 parent 81d3411 commit c366931

File tree

3 files changed

+87
-20
lines changed

3 files changed

+87
-20
lines changed

gluepyter/glue_session.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import warnings
44
from pathlib import Path
55
from typing import TYPE_CHECKING, Dict, Optional, Tuple
6-
76
from glue.core.link_helpers import LinkSame
87
from glue.core.state import GlueSerializer
98
import glue_jupyter as gj
@@ -356,29 +355,40 @@ def add_data(self, file_path: str) -> None:
356355
assert os.path.exists(relative_path)
357356

358357
data = self.app.load_data(str(relative_path))
359-
self._data[data.label] = data
360358

361-
# We generate the data representation and merge it into our ycontent
362-
serializer = GlueSerializer(data)
363-
serialized_data = serializer.dumpo()
359+
# Serialize the data on its own (without other context).
360+
data_serializer = GlueSerializer(data)
361+
data_serializer.dumpo()
362+
363+
# Serialize the previous data without the new one to create a context.
364+
previous_data_serializer = GlueSerializer(self._data)
365+
previous_data_serializer.dumpo()
366+
367+
# We generate the data representation in the previous data context.
368+
serialized_data = [
369+
(previous_data_serializer.id(obj), previous_data_serializer.do(obj))
370+
for oid, obj in list(data_serializer._objs.items())
371+
]
372+
serialized_data = dict(serialized_data)
364373

365374
contents = self._document.contents
366375

367-
# Inject the main data repr
368-
contents[data.label] = serialized_data["__main__"]
369376
# Inject all components
370377
for key, value in serialized_data.items():
371378
if key != "__main__":
372379
contents[key] = value
380+
373381
# Inject the label in the data collection
374-
contents["DataCollection"]["data"].append(data.label)
375-
contents["DataCollection"]["cids"].extend(
376-
cid for cid, comp in serialized_data["__main__"]["components"]
382+
data_collection_name: str = contents.get("__main__", {}).get("data", "")
383+
contents[data_collection_name]["data"].append(data.label)
384+
contents[data_collection_name]["cids"].extend(
385+
cid for cid, comp in serialized_data[data.label]["components"]
377386
)
378-
contents["DataCollection"]["components"].extend(
379-
comp for cid, comp in serialized_data["__main__"]["components"]
387+
contents[data_collection_name]["components"].extend(
388+
comp for cid, comp in serialized_data[data.label]["components"]
380389
)
381390

391+
self._data[data.label] = data
382392
self._document.set(json.dumps(contents))
383393

384394
def _load_data(self) -> None:

gluepyter/glue_utils.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@
1010
load_plugins()
1111

1212

13+
class ErrorWidget:
14+
"""Wrapper of a HTML widget for showing error message"""
15+
16+
def __init__(self, e: Exception, path: str) -> None:
17+
value = f"{type(e).__name__} at line {e.__traceback__.tb_lineno} of {path}: {e}"
18+
self._widget = HTML(value=value)
19+
20+
def show(self):
21+
display(self._widget)
22+
23+
1324
def get_function_info(function_or_helper):
1425
item_info: Dict[str, Dict] = {}
1526
attributes = ["description", "labels1", "labels2", "display"]
@@ -67,12 +78,28 @@ def get_advanced_links():
6778
return advanced_links
6879

6980

70-
class ErrorWidget:
71-
"""Wrapper of a HTML widget for showing error message"""
81+
def nested_compare(value1, value2):
82+
# Compare lists
83+
if isinstance(value1, list) and isinstance(value2, list):
84+
if not len(value1) == len(value2):
85+
return False
7286

73-
def __init__(self, e: Exception, path: str) -> None:
74-
value = f"{type(e).__name__} at line {e.__traceback__.tb_lineno} of {path}: {e}"
75-
self._widget = HTML(value=value)
87+
for v1, v2 in zip(value1, value2):
88+
if not nested_compare(v1, v2):
89+
return False
7690

77-
def show(self):
78-
display(self._widget)
91+
return True
92+
93+
# Compare dict
94+
if isinstance(value1, dict) and isinstance(value2, dict):
95+
for k1, v1 in value1.items():
96+
if k1 not in value2.keys():
97+
return False
98+
99+
if not nested_compare(v1, value2[k1]):
100+
return False
101+
102+
return True
103+
104+
# Compare immutable
105+
return value1 == value2

gluepyter/tests/test_glue_session.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import y_py as Y
2-
from gluepyter.glue_session import SharedGlueSession
2+
from copy import deepcopy
3+
from pathlib import Path
34
from ipywidgets import Output
5+
from gluepyter.glue_session import SharedGlueSession
6+
from gluepyter.glue_utils import nested_compare
47

58

69
def test_init(session_path):
@@ -61,6 +64,33 @@ def test__read_view_state(yglue_session):
6164
assert len(state) > 0
6265

6366

67+
def test_add_data(yglue_session):
68+
yglue_session._load_data()
69+
file_path = Path(__file__).parents[2] / "examples" / "w6_psc.vot"
70+
71+
contents = deepcopy(yglue_session._document.contents)
72+
yglue_session.add_data(file_path)
73+
updated_contents = yglue_session._document.contents
74+
75+
assert "w6_psc" in updated_contents.keys()
76+
77+
# Assert there is no change in previous structure
78+
for key, value in contents.items():
79+
if key == "DataCollection":
80+
continue
81+
assert key in updated_contents.keys()
82+
assert nested_compare(value, updated_contents[key])
83+
84+
# Compare the DataCollection
85+
for key, value in contents["DataCollection"].items():
86+
if key == "data" or key == "cids" or key == "components":
87+
assert not nested_compare(value, updated_contents["DataCollection"][key])
88+
else:
89+
assert nested_compare(value, updated_contents["DataCollection"][key])
90+
91+
assert "w6_psc" in updated_contents["DataCollection"]["data"]
92+
93+
6494
def test_add_identity_link(yglue_session, identity_link):
6595
yglue_session._load_data()
6696
change = {"LinkTest": {"action": "add", "newValue": identity_link}}

0 commit comments

Comments
 (0)