18
18
from pyiron_snippets .colors import SeabornColors
19
19
from pyiron_snippets .dotdict import DotDict
20
20
21
+ from pyiron_workflow import overloading
21
22
from pyiron_workflow .channels import (
22
23
AccumulatingInputSignal ,
23
24
Channel ,
@@ -978,15 +979,56 @@ def save_checkpoint(self, backend: BackendIdentifier | StorageInterface = "pickl
978
979
"""
979
980
self .graph_root .save (backend = backend )
980
981
981
- def load (
982
- self ,
982
+ @classmethod
983
+ def _new_instance_from_storage (
984
+ cls ,
983
985
backend : BackendIdentifier | StorageInterface = "pickle" ,
984
986
only_requested = False ,
985
987
filename : str | Path | None = None ,
988
+ _node : Node | None = None ,
986
989
** kwargs ,
987
990
):
988
991
"""
992
+ Loads a node from file returns its instance.
993
+
994
+ Args:
995
+ backend (str | StorageInterface): The interface to use for serializing the
996
+ node. (Default is "pickle", which loads the standard pickling back end.)
997
+ only_requested (bool): Whether to _only_ try loading from the specified
998
+ backend, or to loop through all available backends. (Default is False,
999
+ try to load whatever you can find.)
1000
+ filename (str | Path | None): The name of the file (without extensions)
1001
+ from which to load the node. (Default is None, which uses the node's
1002
+ lexical path.)
1003
+ **kwargs: back end-specific arguments (only likely to work in combination
1004
+ with :param:`only_requested`, otherwise there's nothing to be specific
1005
+ _to_.)
1006
+
1007
+ Raises:
1008
+ FileNotFoundError: when nothing got loaded.
1009
+ """
1010
+ inst = None
1011
+ for selected_backend in available_backends (
1012
+ backend = backend , only_requested = only_requested
1013
+ ):
1014
+ inst = selected_backend .load (node = _node , filename = filename , ** kwargs )
1015
+ if inst is not None :
1016
+ break
1017
+ if inst is None :
1018
+ raise FileNotFoundError (
1019
+ f"Could not find saved content at { filename } using backend={ backend } "
1020
+ f"using only_request={ only_requested } ."
1021
+ )
1022
+ return inst
989
1023
1024
+ def _update_instance_from_storage (
1025
+ self ,
1026
+ backend : BackendIdentifier | StorageInterface = "pickle" ,
1027
+ only_requested = False ,
1028
+ filename : str | Path | None = None ,
1029
+ ** kwargs ,
1030
+ ):
1031
+ """
990
1032
Loads the node file and set the loaded state as the node's own.
991
1033
992
1034
Args:
@@ -1012,16 +1054,13 @@ def load(
1012
1054
"is the correct thing to do, you can set `self.running=True` where "
1013
1055
"`self` is this node object."
1014
1056
)
1015
- for selected_backend in available_backends (
1016
- backend = backend , only_requested = only_requested
1017
- ):
1018
- inst = selected_backend .load (
1019
- node = self if filename is None else None , filename = filename , ** kwargs
1020
- )
1021
- if inst is not None :
1022
- break
1023
- if inst is None :
1024
- raise FileNotFoundError (f"{ self .label } could not find saved content." )
1057
+ inst = self .__class__ ._new_instance_from_storage (
1058
+ backend = backend ,
1059
+ only_requested = only_requested ,
1060
+ filename = filename ,
1061
+ _node = self if filename is None else None ,
1062
+ ** kwargs ,
1063
+ )
1025
1064
1026
1065
if inst .__class__ != self .__class__ :
1027
1066
raise TypeError (
@@ -1031,6 +1070,44 @@ def load(
1031
1070
)
1032
1071
self .__setstate__ (inst .__getstate__ ())
1033
1072
1073
+ @overloading .overloaded_classmethod (class_method = _new_instance_from_storage )
1074
+ def load (
1075
+ self ,
1076
+ backend : BackendIdentifier | StorageInterface = "pickle" ,
1077
+ only_requested = False ,
1078
+ filename : str | Path | None = None ,
1079
+ ** kwargs ,
1080
+ ):
1081
+ """
1082
+ Load a node from storage, either as a new instance (when used as a class
1083
+ method) or by updating the current instance (when called as a regular instance
1084
+ method).
1085
+
1086
+ Args:
1087
+ backend (str | StorageInterface): The interface to use for serializing the
1088
+ node. (Default is "pickle", which loads the standard pickling back end.)
1089
+ only_requested (bool): Whether to _only_ try loading from the specified
1090
+ backend, or to loop through all available backends. (Default is False,
1091
+ try to load whatever you can find.)
1092
+ filename (str | Path | None): The name of the file (without extensions)
1093
+ from which to load the node. (Default is None, which uses the node's
1094
+ lexical path.)
1095
+ **kwargs: back end-specific arguments (only likely to work in combination
1096
+ with :param:`only_requested`, otherwise there's nothing to be specific
1097
+ _to_.)
1098
+
1099
+ Raises:
1100
+ FileNotFoundError: when nothing got loaded.
1101
+ TypeError: when loading into an exisiting instance and the saved node has a
1102
+ different class name.
1103
+ """
1104
+ return self ._update_instance_from_storage (
1105
+ backend = backend ,
1106
+ only_requested = only_requested ,
1107
+ filename = filename ,
1108
+ ** kwargs ,
1109
+ )
1110
+
1034
1111
load .__doc__ = cast (str , load .__doc__ ) + _save_load_warnings
1035
1112
1036
1113
def delete_storage (
0 commit comments