generated from pyiron/pyiron_module_template
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [minor] Replace `HasToDict` mixin with `HasStateDisplay` mixin Functionality is similar -- the point is to get a nice JSON representation for child classes. But the public interface is different (hence minor flag), and in particular we don't use `to_dict` which might interfere with other pyiron activities. There's also some changes to exactly the display looks like, but since it's just a nice/useful thing for humans to look at, this is non-critical and can be improved with patches as needed. * Remove unused import
- Loading branch information
Showing
8 changed files
with
111 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,76 @@ | ||
from abc import ABC, abstractmethod | ||
from abc import ABC | ||
from json import dumps | ||
|
||
from pyiron_workflow.mixin.has_interface_mixins import UsesState | ||
|
||
class HasToDict(ABC): | ||
@abstractmethod | ||
def to_dict(self): | ||
pass | ||
|
||
def _repr_json_(self): | ||
return self.to_dict() | ||
class HasStateDisplay(UsesState, ABC): | ||
""" | ||
A mixin that leverages :meth:`__getstate__` to automatically build a half-decent | ||
JSON-compatible representation dictionary. | ||
Child classes can over-ride :meth:`display_state` to add or remove elements from | ||
the display dictionary, e.g. to (optionally) expose state elements that would | ||
otherwise be private or to show properties that are computed and not stored in | ||
state, or (mandatory -- JSON demands it) remove recursion from the state. | ||
Provides a :meth:`_repr_json_` method leveraging this beautified state dictionary | ||
to give a standard JSON representation in Jupyter notebooks. | ||
""" | ||
|
||
def display_state( | ||
self, state: dict | None = None, ignore_private: bool = True | ||
) -> dict: | ||
""" | ||
A dictionary of JSON-compatible objects based on the object state (plus | ||
whatever modifications to the state the class designer has chosen to make). | ||
Anything that fails to dump to JSON gets cast as a string and then dumped. | ||
Args: | ||
state (dict|None): The starting state. Default is None which uses | ||
`__getstate__`, but available in case child classes want to first | ||
sanitize the state values. | ||
ignore_private (bool): Whether to ignore or include any state element | ||
whose key starts with `'_'`. Default is True, only show public data. | ||
def info(self): | ||
print(dumps(self.to_dict(), indent=2)) | ||
Returns: | ||
dict: | ||
""" | ||
display = dict(self.__getstate__()) if state is None else state | ||
to_del = [] | ||
for k, v in display.items(): | ||
if ignore_private and k.startswith("_"): | ||
to_del.append(k) | ||
|
||
if isinstance(v, HasStateDisplay): | ||
display[k] = v.display_state(ignore_private=ignore_private) | ||
else: | ||
try: | ||
display[k] = dumps(v) | ||
except TypeError: | ||
display[k] = dumps(str(v)) | ||
|
||
for k in to_del: | ||
del display[k] | ||
|
||
return display | ||
|
||
def _repr_json_(self): | ||
return self.display_state() | ||
|
||
def __str__(self): | ||
return str(self.to_dict()) | ||
@staticmethod | ||
def _make_entry_public(state: dict, private_key: str, public_key: str): | ||
if private_key not in state.keys(): | ||
raise ValueError( | ||
f"Can't make {private_key} public, it was not found among " | ||
f"{list(state.keys())}" | ||
) | ||
if public_key in state.keys(): | ||
raise ValueError( | ||
f"Can't make {private_key} public, {public_key} is already a key in" | ||
f" the dict!" | ||
) | ||
state[public_key] = state[private_key] | ||
del state[private_key] | ||
return state |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters