Skip to content

Commit

Permalink
Merge pull request #1620 from pyiron/server
Browse files Browse the repository at this point in the history
Revert changes to DataContainer storage format
  • Loading branch information
jan-janssen authored Aug 26, 2024
2 parents 2ca2d67 + 3ccfa33 commit 959ad9d
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unittests_old.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Setup Mambaforge
uses: conda-incubator/setup-miniconda@v3
with:
python-version: '3.9'
python-version: '3.10'
miniforge-variant: Mambaforge
channels: conda-forge
channel-priority: strict
Expand Down
27 changes: 25 additions & 2 deletions pyiron_base/interfaces/has_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"""

from abc import ABC, abstractmethod
from collections import defaultdict
from typing import Any

from pyiron_base.interfaces.has_hdf import HasHDF
Expand Down Expand Up @@ -54,7 +55,7 @@ def create_from_dict(obj_dict):
type_field = obj_dict["TYPE"]
module_path, class_name = _extract_module_class_name(type_field)
class_object = _import_class(module_path, class_name)
version = obj_dict.get("VERSION", None)
version = obj_dict.get("DICT_VERSION", None)
obj = class_object.instantiate(obj_dict, version)
obj.from_dict(obj_dict, version)
return obj
Expand Down Expand Up @@ -122,6 +123,9 @@ def load(inner_dict):
return {k: load(v) for k, v in inner_dict.items()}
return create_from_dict(inner_dict)

obj_dict = self._split_children_dict(obj_dict)
if version is None:
version = obj_dict.get("DICT_VERSION", None)
self._from_dict({k: load(v) for k, v in obj_dict.items()}, version)

@abstractmethod
Expand Down Expand Up @@ -208,9 +212,28 @@ def _join_children_dict(children: dict[str, dict[str, Any]]) -> dict[str, Any]:
return {
"/".join((k1, k2)): v2
for k1, v1 in children.items()
for k2, v2 in v2.items()
for k2, v2 in v1.items()
}

@staticmethod
def _split_children_dict(
obj_dict: dict[str, Any],
) -> dict[str, Any | dict[str, Any]]:
"""
Undoes _join_children_dict.
"""
subs = defaultdict(dict)
plain = {}
for k, v in obj_dict.items():
if "/" not in k:
plain[k] = v
continue
root, k = k.split("/", maxsplit=1)
subs[root][k] = v
# using update keeps type stability, i.e. we always return a plain dict
plain.update(subs)
return plain


class HasHDFfromDict(HasHDF, HasDict):
"""
Expand Down
23 changes: 20 additions & 3 deletions pyiron_base/storage/datacontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"HDF_VERSION",
"DICT_VERSION",
"READ_ONLY",
"KEY_ORDER",
]


Expand Down Expand Up @@ -827,6 +828,7 @@ def _on_unlock(self):


class DataContainer(DataContainerBase, HasHDF, HasDict):
__dict_version__ = "0.2.0"
__doc__ = f"""{DataContainerBase.__doc__}
If instantiated with the argument `lazy=True`, data read from HDF5 later via :method:`.from_hdf` are not actually
Expand Down Expand Up @@ -1027,13 +1029,28 @@ def to(v):
return data

def _to_dict(self):
return {"data": self.to_builtin(), "READ_ONLY": self.read_only}
# stringify keys in case we are acting like a list
data = {str(k): v for k, v in dict(self).items()}
order = list(data)
data["READ_ONLY"] = self.read_only
data["KEY_ORDER"] = order
return data

def _from_dict(self, obj_dict, version=None):
if version == "0.2.0":
order = obj_dict.pop("KEY_ORDER")
else:
order = None
self.read_only = obj_dict.pop("READ_ONLY", False)
for key in _internal_hdf_nodes:
obj_dict.pop(key, None)
with self.unlocked():
self.clear()
self.update(obj_dict["data"], wrap=True)
self.read_only = obj_dict.get("READ_ONLY", False)
if order is not None:
for key in order:
self[key] = obj_dict[key]
else:
self.update(obj_dict)


HDFStub.register(DataContainer, lambda h, g: h[g].to_object(lazy=True))
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Intended Audience :: Science/Research",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand Down

0 comments on commit 959ad9d

Please sign in to comment.