bagofholding 0.0.2__tar.gz → 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bagofholding-0.0.3/.gitignore +13 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/PKG-INFO +11 -13
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/__init__.py +7 -2
- bagofholding-0.0.3/bagofholding/_version.py +21 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/__init__.py +25 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/_version.py +21 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/bag.py +266 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/content.py +897 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/exceptions.py +44 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/h5/__init__.py +0 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/h5/bag.py +183 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/h5/content.py +29 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/h5/context.py +58 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/h5/dtypes.py +73 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/h5/triebag.py +322 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/metadata.py +197 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/retrieve.py +52 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/trie.py +178 -0
- bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/widget.py +109 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/pyproject.toml +18 -15
- bagofholding-0.0.2/MANIFEST.in +0 -1
- bagofholding-0.0.2/bagofholding/_version.py +0 -21
- bagofholding-0.0.2/bagofholding.egg-info/PKG-INFO +0 -204
- bagofholding-0.0.2/bagofholding.egg-info/SOURCES.txt +0 -25
- bagofholding-0.0.2/bagofholding.egg-info/dependency_links.txt +0 -1
- bagofholding-0.0.2/bagofholding.egg-info/requires.txt +0 -10
- bagofholding-0.0.2/bagofholding.egg-info/top_level.txt +0 -1
- bagofholding-0.0.2/setup.cfg +0 -4
- bagofholding-0.0.2/setup.py +0 -8
- {bagofholding-0.0.2 → bagofholding-0.0.3}/LICENSE +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/bag.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/content.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/exceptions.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/h5/__init__.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/h5/bag.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/h5/content.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/h5/context.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/h5/dtypes.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/h5/triebag.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/metadata.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/retrieve.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/trie.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/bagofholding/widget.py +0 -0
- {bagofholding-0.0.2 → bagofholding-0.0.3}/docs/README.md +0 -0
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bagofholding
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: bagofholding - browsable, partially-reloadable serialization for pickleable python objects.
|
|
5
|
+
Project-URL: Homepage, https://pyiron.org/
|
|
6
|
+
Project-URL: Documentation, https://bagofholding.readthedocs.io
|
|
7
|
+
Project-URL: Repository, https://github.com/pyiron/bagofholding
|
|
5
8
|
Author-email: Liam Huber <liamhuber@greyhavensolutions.com>
|
|
6
9
|
License: BSD 3-Clause License
|
|
7
10
|
|
|
@@ -31,31 +34,26 @@ License: BSD 3-Clause License
|
|
|
31
34
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
32
35
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
33
36
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
34
|
-
|
|
35
|
-
Project-URL: Homepage, https://pyiron.org/
|
|
36
|
-
Project-URL: Documentation, https://bagofholding.readthedocs.io
|
|
37
|
-
Project-URL: Repository, https://github.com/pyiron/bagofholding
|
|
37
|
+
License-File: LICENSE
|
|
38
38
|
Keywords: pyiron
|
|
39
39
|
Classifier: Development Status :: 3 - Alpha
|
|
40
|
-
Classifier: Topic :: Scientific/Engineering
|
|
41
|
-
Classifier: License :: OSI Approved :: BSD License
|
|
42
40
|
Classifier: Intended Audience :: Science/Research
|
|
41
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
43
42
|
Classifier: Operating System :: OS Independent
|
|
44
43
|
Classifier: Programming Language :: Python :: 3.12
|
|
45
44
|
Classifier: Programming Language :: Python :: 3.13
|
|
45
|
+
Classifier: Topic :: Scientific/Engineering
|
|
46
46
|
Requires-Python: <3.14,>=3.12
|
|
47
|
-
Description-Content-Type: text/markdown
|
|
48
|
-
License-File: LICENSE
|
|
49
47
|
Requires-Dist: bidict==0.23.1
|
|
50
48
|
Requires-Dist: h5py<3.15.0,>=3.14.0
|
|
51
49
|
Requires-Dist: mpi4py<4.1.0,>=4.0.1
|
|
52
50
|
Requires-Dist: numpy<2.4.0,>=2.3.0
|
|
53
51
|
Requires-Dist: pygtrie<2.6.0,>=2.5.0
|
|
54
|
-
Requires-Dist:
|
|
52
|
+
Requires-Dist: pyiron-snippets==0.2.0
|
|
55
53
|
Provides-Extra: widget
|
|
56
|
-
Requires-Dist: ipytree==0.2.2; extra ==
|
|
57
|
-
Requires-Dist: traitlets==5.14.3; extra ==
|
|
58
|
-
|
|
54
|
+
Requires-Dist: ipytree==0.2.2; extra == 'widget'
|
|
55
|
+
Requires-Dist: traitlets==5.14.3; extra == 'widget'
|
|
56
|
+
Description-Content-Type: text/markdown
|
|
59
57
|
|
|
60
58
|
# bagofholding
|
|
61
59
|
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import importlib.metadata
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
try:
|
|
4
|
+
# Installed package will find its version
|
|
5
|
+
__version__ = importlib.metadata.version(__name__)
|
|
6
|
+
except importlib.metadata.PackageNotFoundError:
|
|
7
|
+
# Repository clones will register an unknown version
|
|
8
|
+
__version__ = "0.0.0+unknown"
|
|
4
9
|
|
|
5
10
|
from bagofholding.exceptions import BagMismatchError as BagMismatchError
|
|
6
11
|
from bagofholding.exceptions import BagOfHoldingError as BagOfHoldingError
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
+
|
|
6
|
+
TYPE_CHECKING = False
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from typing import Tuple
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
11
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
12
|
+
else:
|
|
13
|
+
VERSION_TUPLE = object
|
|
14
|
+
|
|
15
|
+
version: str
|
|
16
|
+
__version__: str
|
|
17
|
+
__version_tuple__: VERSION_TUPLE
|
|
18
|
+
version_tuple: VERSION_TUPLE
|
|
19
|
+
|
|
20
|
+
__version__ = version = '0.0.3'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 0, 3)
|
bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/__init__.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import importlib.metadata
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
# Installed package will find its version
|
|
5
|
+
__version__ = importlib.metadata.version(__name__)
|
|
6
|
+
except importlib.metadata.PackageNotFoundError:
|
|
7
|
+
# Repository clones will register an unknown version
|
|
8
|
+
__version__ = "0.0.0+unknown"
|
|
9
|
+
|
|
10
|
+
from bagofholding.exceptions import BagMismatchError as BagMismatchError
|
|
11
|
+
from bagofholding.exceptions import BagOfHoldingError as BagOfHoldingError
|
|
12
|
+
from bagofholding.exceptions import EnvironmentMismatchError as EnvironmentMismatchError
|
|
13
|
+
from bagofholding.exceptions import FileAlreadyOpenError as FileAlreadyOpenError
|
|
14
|
+
from bagofholding.exceptions import FileNotOpenError as FileNotOpenError
|
|
15
|
+
from bagofholding.exceptions import FilepathError as FilepathError
|
|
16
|
+
from bagofholding.exceptions import InvalidMetadataError as InvalidMetadataError
|
|
17
|
+
from bagofholding.exceptions import ModuleForbiddenError as ModuleForbiddenError
|
|
18
|
+
from bagofholding.exceptions import NotAGroupError as NotAGroupError
|
|
19
|
+
from bagofholding.exceptions import NoVersionError as NoVersionError
|
|
20
|
+
from bagofholding.exceptions import PickleProtocolError as PickleProtocolError
|
|
21
|
+
from bagofholding.exceptions import (
|
|
22
|
+
StringReductionNotImportableError as StringReductionNotImportableError,
|
|
23
|
+
)
|
|
24
|
+
from bagofholding.h5.bag import H5Bag as H5Bag
|
|
25
|
+
from bagofholding.h5.triebag import TrieH5Bag as TrieH5Bag
|
bagofholding-0.0.3/cached-miniforge/my-env/lib/python3.1/site-packages/bagofholding/_version.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
+
|
|
6
|
+
TYPE_CHECKING = False
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from typing import Tuple
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
11
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
12
|
+
else:
|
|
13
|
+
VERSION_TUPLE = object
|
|
14
|
+
|
|
15
|
+
version: str
|
|
16
|
+
__version__: str
|
|
17
|
+
__version_tuple__: VERSION_TUPLE
|
|
18
|
+
version_tuple: VERSION_TUPLE
|
|
19
|
+
|
|
20
|
+
__version__ = version = '0.0.3'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 0, 3)
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The core user-facing object.
|
|
3
|
+
|
|
4
|
+
Full implementations of bags should guarantee the key features promised by the package:
|
|
5
|
+
- Storage and retrieval of arbitrary pickleable python objects
|
|
6
|
+
- Metadata preservation
|
|
7
|
+
- Versioning verification
|
|
8
|
+
- Browsing without loading
|
|
9
|
+
- Partial reloading
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import abc
|
|
15
|
+
import dataclasses
|
|
16
|
+
import os.path
|
|
17
|
+
import pathlib
|
|
18
|
+
import pickle
|
|
19
|
+
from collections.abc import Iterator, Mapping
|
|
20
|
+
from typing import (
|
|
21
|
+
Any,
|
|
22
|
+
ClassVar,
|
|
23
|
+
Self,
|
|
24
|
+
SupportsIndex,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
import bidict
|
|
28
|
+
from pyiron_snippets import import_alarm
|
|
29
|
+
|
|
30
|
+
from bagofholding.content import BespokeItem, Packer, pack, unpack
|
|
31
|
+
from bagofholding.exceptions import BagMismatchError, InvalidMetadataError
|
|
32
|
+
from bagofholding.metadata import (
|
|
33
|
+
HasFieldIterator,
|
|
34
|
+
HasVersionInfo,
|
|
35
|
+
Metadata,
|
|
36
|
+
VersionScrapingMap,
|
|
37
|
+
VersionValidatorType,
|
|
38
|
+
get_version,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
from bagofholding.widget import BagTree
|
|
43
|
+
|
|
44
|
+
alarm = import_alarm.ImportAlarm()
|
|
45
|
+
except (ImportError, ModuleNotFoundError):
|
|
46
|
+
alarm = import_alarm.ImportAlarm(
|
|
47
|
+
"The browsing widget relies on ipytree and traitlets, but this was "
|
|
48
|
+
"unavailable. You can get a text-representation of all available paths with "
|
|
49
|
+
":meth:`bagofholding.bag.Bag.list_paths`.",
|
|
50
|
+
_fail_on_warning=True,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
PATH_DELIMITER = "/"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclasses.dataclass(frozen=True)
|
|
57
|
+
class BagInfo(HasVersionInfo, HasFieldIterator):
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class Bag(Packer, Mapping[str, Metadata | None], abc.ABC):
|
|
62
|
+
"""
|
|
63
|
+
Bags are the user-facing object.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
bag_info: BagInfo
|
|
67
|
+
storage_root: ClassVar[str] = "object"
|
|
68
|
+
filepath: pathlib.Path
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
def get_bag_info(cls) -> BagInfo:
|
|
72
|
+
return BagInfo(
|
|
73
|
+
qualname=cls.__qualname__,
|
|
74
|
+
module=cls.__module__,
|
|
75
|
+
version=cls.get_version(),
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
@classmethod
|
|
79
|
+
def _bag_info_class(cls) -> type[BagInfo]:
|
|
80
|
+
return BagInfo
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
def save(
|
|
84
|
+
cls,
|
|
85
|
+
obj: Any,
|
|
86
|
+
filepath: str | pathlib.Path,
|
|
87
|
+
require_versions: bool = False,
|
|
88
|
+
forbidden_modules: list[str] | tuple[str, ...] = (),
|
|
89
|
+
version_scraping: VersionScrapingMap | None = None,
|
|
90
|
+
_pickle_protocol: SupportsIndex = pickle.DEFAULT_PROTOCOL,
|
|
91
|
+
overwrite_existing: bool = True,
|
|
92
|
+
) -> None:
|
|
93
|
+
"""
|
|
94
|
+
Save a python object to file.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
obj (Any): The (pickleble) python object to be saved.
|
|
98
|
+
filepath (str|pathlib.Path): The path to save the object to.
|
|
99
|
+
require_versions (bool): Whether to require a metadata for reduced
|
|
100
|
+
and complex objects to contain a non-None version. (Default is False,
|
|
101
|
+
objects can be stored from non-versioned packages/modules.)
|
|
102
|
+
forbidden_modules (list[str] | tuple[str, ...] | None): Do not allow saving
|
|
103
|
+
objects whose root-most modules are listed here. (Default is an empty
|
|
104
|
+
tuple, i.e. don't disallow anything.) This is particularly useful to
|
|
105
|
+
disallow `"__main__"` to improve the odds that objects will actually
|
|
106
|
+
be loadable in the future.
|
|
107
|
+
version_scraping (dict[str, Callable[[str], str]] | None): An optional
|
|
108
|
+
dictionary mapping module names to a callable that takes this name and
|
|
109
|
+
returns a version (or None). The default callable imports the module
|
|
110
|
+
string and looks for a `__version__` attribute.
|
|
111
|
+
"""
|
|
112
|
+
if os.path.exists(filepath):
|
|
113
|
+
if overwrite_existing and os.path.isfile(filepath):
|
|
114
|
+
os.remove(filepath)
|
|
115
|
+
else:
|
|
116
|
+
raise FileExistsError(f"{filepath} already exists or is not a file.")
|
|
117
|
+
bag = cls(filepath)
|
|
118
|
+
bag._pack_bag_info()
|
|
119
|
+
pack(
|
|
120
|
+
obj,
|
|
121
|
+
bag,
|
|
122
|
+
bag.storage_root,
|
|
123
|
+
bidict.bidict(),
|
|
124
|
+
[],
|
|
125
|
+
require_versions,
|
|
126
|
+
forbidden_modules,
|
|
127
|
+
version_scraping,
|
|
128
|
+
_pickle_protocol=_pickle_protocol,
|
|
129
|
+
)
|
|
130
|
+
bag._write()
|
|
131
|
+
|
|
132
|
+
@classmethod
|
|
133
|
+
def get_version(cls) -> str:
|
|
134
|
+
return str(get_version(cls.__module__, {}))
|
|
135
|
+
|
|
136
|
+
def __init__(
|
|
137
|
+
self, filepath: str | pathlib.Path, *args: object, **kwargs: Any
|
|
138
|
+
) -> None:
|
|
139
|
+
super().__init__(*args, **kwargs)
|
|
140
|
+
self.filepath = pathlib.Path(filepath)
|
|
141
|
+
if os.path.isfile(self.filepath):
|
|
142
|
+
self.bag_info = self._unpack_bag_info()
|
|
143
|
+
if not self.validate_bag_info(self.bag_info, self.get_bag_info()):
|
|
144
|
+
raise BagMismatchError(
|
|
145
|
+
f"The bag class {self.__class__} does not match the bag saved at "
|
|
146
|
+
f"{filepath}; class info is {self.get_bag_info()}, but the info saved "
|
|
147
|
+
f"is {self.bag_info}"
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
@abc.abstractmethod
|
|
151
|
+
def _pack_field(self, path: str, key: str, value: str) -> None: ...
|
|
152
|
+
|
|
153
|
+
@abc.abstractmethod
|
|
154
|
+
def _unpack_field(self, path: str, key: str) -> str | None: ...
|
|
155
|
+
|
|
156
|
+
@staticmethod
|
|
157
|
+
def validate_bag_info(bag_info: BagInfo, reference: BagInfo) -> bool:
|
|
158
|
+
return bag_info == reference
|
|
159
|
+
|
|
160
|
+
def load(
|
|
161
|
+
self,
|
|
162
|
+
path: str = storage_root,
|
|
163
|
+
version_validator: VersionValidatorType = "exact",
|
|
164
|
+
version_scraping: VersionScrapingMap | None = None,
|
|
165
|
+
) -> Any:
|
|
166
|
+
return unpack(
|
|
167
|
+
self,
|
|
168
|
+
path,
|
|
169
|
+
{},
|
|
170
|
+
version_validator=version_validator,
|
|
171
|
+
version_scraping=version_scraping,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
def __getitem__(self, path: str) -> Metadata:
|
|
175
|
+
return self.unpack_metadata(path)
|
|
176
|
+
|
|
177
|
+
@abc.abstractmethod
|
|
178
|
+
def list_paths(self) -> list[str]:
|
|
179
|
+
"""A list of all available content paths."""
|
|
180
|
+
|
|
181
|
+
@alarm
|
|
182
|
+
def widget(self): # type: ignore[no-untyped-def]
|
|
183
|
+
return BagTree(self)
|
|
184
|
+
|
|
185
|
+
def browse(self): # type: ignore[no-untyped-def]
|
|
186
|
+
try:
|
|
187
|
+
return self.widget()
|
|
188
|
+
except ImportError:
|
|
189
|
+
return self.list_paths()
|
|
190
|
+
|
|
191
|
+
def __len__(self) -> int:
|
|
192
|
+
return len(self.list_paths())
|
|
193
|
+
|
|
194
|
+
def __iter__(self) -> Iterator[str]:
|
|
195
|
+
return iter(self.list_paths())
|
|
196
|
+
|
|
197
|
+
def join(self, *paths: str) -> str:
|
|
198
|
+
return PATH_DELIMITER.join(paths)
|
|
199
|
+
|
|
200
|
+
@staticmethod
|
|
201
|
+
def pickle_check(
|
|
202
|
+
obj: Any, raise_exceptions: bool = True, print_message: bool = False
|
|
203
|
+
) -> str | None:
|
|
204
|
+
"""
|
|
205
|
+
A simple helper to check if an object can be pickled and unpickled.
|
|
206
|
+
Useful if you run into trouble saving or loading and want to see whether the
|
|
207
|
+
underlying object is compliant with pickle-ability requirements to begin with.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
obj: The object to test for pickling support.
|
|
211
|
+
raise_exceptions: If True, re-raise any exception encountered.
|
|
212
|
+
print_message: If True, print the exception message on failure.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
None if pickling is successful; otherwise, returns the exception message as a string.
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
try:
|
|
219
|
+
pickle.loads(pickle.dumps(obj))
|
|
220
|
+
except Exception as e:
|
|
221
|
+
if print_message:
|
|
222
|
+
print(e)
|
|
223
|
+
if raise_exceptions:
|
|
224
|
+
raise e
|
|
225
|
+
return str(e)
|
|
226
|
+
return None
|
|
227
|
+
|
|
228
|
+
def _pack_fields(self, dataclass: HasFieldIterator, path: str) -> None:
|
|
229
|
+
for k, v in dataclass.field_items():
|
|
230
|
+
if v is not None:
|
|
231
|
+
self._pack_field(path, k, v)
|
|
232
|
+
|
|
233
|
+
def _unpack_fields(
|
|
234
|
+
self, dataclass_type: type[HasFieldIterator], path: str
|
|
235
|
+
) -> dict[str, str | None]:
|
|
236
|
+
field_values: dict[str, str | None] = {}
|
|
237
|
+
for k in dataclass_type.__dataclass_fields__:
|
|
238
|
+
field_values[k] = self._unpack_field(path, k)
|
|
239
|
+
return field_values
|
|
240
|
+
|
|
241
|
+
def _pack_bag_info(self) -> None:
|
|
242
|
+
self._pack_fields(self.get_bag_info(), PATH_DELIMITER)
|
|
243
|
+
|
|
244
|
+
def _unpack_bag_info(self) -> BagInfo:
|
|
245
|
+
return self._bag_info_class()(
|
|
246
|
+
**self._unpack_fields(self._bag_info_class(), PATH_DELIMITER)
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
def _write(self) -> None:
|
|
250
|
+
return
|
|
251
|
+
|
|
252
|
+
def pack_metadata(self, metadata: Metadata, path: str) -> None:
|
|
253
|
+
self._pack_fields(metadata, path)
|
|
254
|
+
return None
|
|
255
|
+
|
|
256
|
+
def unpack_metadata(self, path: str) -> Metadata:
|
|
257
|
+
metadata = self._unpack_fields(Metadata, path)
|
|
258
|
+
content_type = metadata.pop("content_type", None)
|
|
259
|
+
if content_type is None:
|
|
260
|
+
raise InvalidMetadataError(f"Metadata at {path} is missing a content type")
|
|
261
|
+
return Metadata(content_type, **metadata)
|
|
262
|
+
|
|
263
|
+
def get_bespoke_content_class(
|
|
264
|
+
self, obj: object
|
|
265
|
+
) -> type[BespokeItem[Any, Self]] | None:
|
|
266
|
+
return None
|