1818from pyiron_snippets .colors import SeabornColors
1919from pyiron_snippets .dotdict import DotDict
2020
21+ from pyiron_workflow import overloading
2122from pyiron_workflow .channels import (
2223 AccumulatingInputSignal ,
2324 Channel ,
@@ -978,15 +979,56 @@ def save_checkpoint(self, backend: BackendIdentifier | StorageInterface = "pickl
978979 """
979980 self .graph_root .save (backend = backend )
980981
981- def load (
982- self ,
982+ @classmethod
983+ def _new_instance_from_storage (
984+ cls ,
983985 backend : BackendIdentifier | StorageInterface = "pickle" ,
984986 only_requested = False ,
985987 filename : str | Path | None = None ,
988+ _node : Node | None = None ,
986989 ** kwargs ,
987990 ):
988991 """
992+ Loads a node from file returns its instance.
989993
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
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+ """
9901032 Loads the node file and set the loaded state as the node's own.
9911033
9921034 Args:
@@ -995,8 +1037,8 @@ def load(
9951037 only_requested (bool): Whether to _only_ try loading from the specified
9961038 backend, or to loop through all available backends. (Default is False,
9971039 try to load whatever you can find.)
998- filename (str | Path | None): The name of the file (without extensions) at
999- which to save the node. (Default is None, which uses the node's
1040+ filename (str | Path | None): The name of the file (without extensions)
1041+ from which to load the node. (Default is None, which uses the node's
10001042 lexical path.)
10011043 **kwargs: back end-specific arguments (only likely to work in combination
10021044 with :param:`only_requested`, otherwise there's nothing to be specific
@@ -1012,16 +1054,13 @@ def load(
10121054 "is the correct thing to do, you can set `self.running=True` where "
10131055 "`self` is this node object."
10141056 )
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+ )
10251064
10261065 if inst .__class__ != self .__class__ :
10271066 raise TypeError (
@@ -1031,6 +1070,44 @@ def load(
10311070 )
10321071 self .__setstate__ (inst .__getstate__ ())
10331072
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+
10341111 load .__doc__ = cast (str , load .__doc__ ) + _save_load_warnings
10351112
10361113 def delete_storage (
@@ -1048,12 +1125,11 @@ def delete_storage(
10481125 Args:
10491126 backend (str | StorageInterface): The interface to use for serializing the
10501127 node. (Default is "pickle", which loads the standard pickling back end.)
1051- only_requested (bool): Whether to _only_ try loading from the specified
1052- backend, or to loop through all available backends. (Default is False,
1053- try to load whatever you can find.)
1054- filename (str | Path | None): The name of the file (without extensions) at
1055- which to save the node. (Default is None, which uses the node's
1056- lexical path.)
1128+ only_requested (bool): Whether to _only_ search for files using the
1129+ specifiedmbackend, or to loop through all available backends. (Default
1130+ is False, try to remove whatever you can find.)
1131+ filename (str | Path | None): The name of the file (without extensions) to
1132+ remove. (Default is None, which uses the node's lexical path.)
10571133 delete_even_if_not_empty (bool): Whether to delete the file even if it is
10581134 not empty. (Default is False, which will only delete the file if it is
10591135 empty, i.e. has no content in it.)
@@ -1084,12 +1160,11 @@ def has_saved_content(
10841160 Args:
10851161 backend (str | StorageInterface): The interface to use for serializing the
10861162 node. (Default is "pickle", which loads the standard pickling back end.)
1087- only_requested (bool): Whether to _only_ try loading from the specified
1088- backend, or to loop through all available backends. (Default is False,
1089- try to load whatever you can find.)
1090- filename (str | Path | None): The name of the file (without extensions) at
1091- which to save the node. (Default is None, which uses the node's
1092- lexical path.)
1163+ only_requested (bool): Whether to _only_ search for files using the
1164+ specified backend, or to loop through all available backends. (Default
1165+ is False, try to finding whatever you can find.)
1166+ filename (str | Path | None): The name of the file (without extensions) to
1167+ look for. (Default is None, which uses the node's lexical path.)
10931168 **kwargs: back end-specific arguments (only likely to work in combination
10941169 with :param:`only_requested`, otherwise there's nothing to be specific
10951170 _to_.)
0 commit comments