ezarr 1.0.0__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.
ezarr-1.0.0/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ __pycache__
2
+ *.vim
@@ -0,0 +1,17 @@
1
+ fail_fast: true
2
+
3
+ repos:
4
+ - repo: https://github.com/astral-sh/ruff-pre-commit
5
+ # Ruff version.
6
+ rev: v0.11.13
7
+ hooks:
8
+ # Run the linter.
9
+ - id: ruff-check
10
+ name: ruff fix
11
+ args: [ --fix, --output-format, concise ]
12
+ # Fix old typing and syntax
13
+ - id: ruff-check
14
+ name: ruff update
15
+ args: [ --fix, --select, UP,F401, --output-format, concise ]
16
+ # Run the formatter.
17
+ - id: ruff-format
@@ -0,0 +1 @@
1
+ 3.12
ezarr-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,132 @@
1
+ Metadata-Version: 2.4
2
+ Name: ezarr
3
+ Version: 1.0.0
4
+ Summary: Tools for easily working with Zarr groups and arrays
5
+ Author-email: Matteo Bouvier <matteo.bouvier@lyon.unicancer.fr>
6
+ Requires-Python: >=3.12
7
+ Requires-Dist: zarr>=3
8
+ Description-Content-Type: text/markdown
9
+
10
+ # eZarr
11
+
12
+ Easily store any Python object inside [zarr](https://zarr.readthedocs.io/en/latest/) hierarchies.
13
+ This package defines proxies for regular Python lists (EZList) and dicts (EZDict), built as wrappers around zarr Arrays and Groups.
14
+ It also defines a Protocol for writing and loading any object in zarr hierarchies.
15
+
16
+ ## EZList
17
+ An EZlist is a proxy for a Python list built on top of a zarr.Array.
18
+ It allows storing mixed arbitrary objects in a 1 dimensional sequence.
19
+
20
+ ### Examples
21
+ ```python
22
+ >>> from ezarr import EZList
23
+ >>> from pathlib import Path
24
+
25
+ # EZList creation from a zarr.Array:
26
+ >>> EZList(zarr.array([1, 2, 3]))
27
+ EZList[1, 2, 3]
28
+
29
+ # EZList creation from a list:
30
+ >>> data = [1, "some text", Path("some/path.txt")]
31
+ >>> ez_list = EZList.from_list(data, store={}, name="data")
32
+ # ~~ ~~~~ a name for the list inside the store
33
+ # |
34
+ # or any zarr StoreLike object to store the list
35
+
36
+ >>> ez_list
37
+ EZList[1, 'some text', PosixPath('some/path.txt')]
38
+
39
+ # EZLists support general list methods:
40
+ >>> ez_list[0]
41
+ 1
42
+
43
+ >>> del ez_list[1]
44
+ >>> ez_list
45
+ EZList[1, PosixPath('some/path.txt')]
46
+
47
+ >>> ez_list.append(3.14)
48
+ >>> ez_list
49
+ EZList[1, PosixPath('some/path.txt'), 3.14]
50
+
51
+ >>> ez_list.insert(0, [1, 2, 3])
52
+ >>> ez_list
53
+ EZList[[1, 2, 3], 1, PosixPath('/some/path.txt'), 3.14]
54
+
55
+ # EZList save to zarr store:
56
+ >>> ez_list.save("path/to/store", name="saved_list")
57
+
58
+ # EZList load from zarr store:
59
+ >>> EZList.open("path/to/store", name="saved_list")
60
+ EZList[[1, 2, 3], 1, PosixPath('/some/path.txt'), 3.14]
61
+
62
+ # EZList conversion to a regular list:
63
+ >>> ez_list.copy()
64
+ [[1, 2, 3], 1, PosixPath('some/path.txt'), 3.14]
65
+ ```
66
+
67
+ ## EZDict
68
+ An EZDict is a proxy for a Python dict built on top of a zarr.Group.
69
+ It expands zarr.Groups to store and retrieve arbitrary objects.
70
+
71
+ ### Examples
72
+ ```python
73
+ >>> from ezarr import EZDict
74
+
75
+ # EZdDct creation for a zarr.Group:
76
+ >>> EZDict(zarr.open_group({}))
77
+ EZDict{}
78
+
79
+ # EZDict creation for a dict:
80
+ >>> data = {"a": 1, "b": [1, 2, 3], "c": {"d": "some text"}}
81
+ >>> ez_dict = EZDict.from_dict(data, store={})
82
+ # ~~ or any zarr StoreLike object to store the dict into # |
83
+
84
+ # EZDict lazy representation:
85
+ >>> ez_dict
86
+ EZDict{
87
+ a: 1,
88
+ b: [1 2 3],
89
+ c: {...} # <-- note the nested dict was not loaded for the representation
90
+ }
91
+
92
+ # EZDict save to zarr store:
93
+ >>> ez_dict.save("path/to/store", name="saved_dict")
94
+
95
+ # EZDict load from zarr store:
96
+ >>> EZDict.open("path/to/store", name="saved_dict")
97
+ EZDict{
98
+ a: 1,
99
+ b: [1 2 3],
100
+ c: {...}
101
+ }
102
+
103
+ # EZDict conversion to a regular dict:
104
+ >>> ez_dict.copy()
105
+ {'a': np.int64(1), 'b': array([1, 2, 3]), 'c': {'d': np.str_('some text')}}
106
+
107
+ ```
108
+
109
+ ## SupportsEZReadWrite
110
+ The `SupportsEZReadWrite` protocol, once implemented on an object, allows it to be store in and retrieved from a zarr hierarchy.
111
+
112
+ ```python
113
+ @runtime_checkable
114
+ class SupportsEZRead(Protocol):
115
+ @classmethod
116
+ def __ez_read__(cls, grp: zarr.Group) -> Self: ...
117
+
118
+
119
+ @runtime_checkable
120
+ class SupportsEZWrite(Protocol):
121
+ def __ez_write__(self, grp: zarr.Group) -> None: ...
122
+
123
+
124
+ @runtime_checkable
125
+ class SupportsEZReadWrite(SupportsEZRead, SupportsEZWrite, Protocol): ...
126
+ ```
127
+
128
+ This protocol has 2 parts:
129
+ - `SupportsEZRead` defines the classmethod `__ez_read__(cls, grp: zarr.Group) -> Self` for reconstructing an object from a zarr.Group.
130
+ - `SupportsEZWrite` defines the method `__ez_write__(self, grp: zarr.Group) -> None` for storing an object in a zarr.Group.
131
+
132
+ Once implemented on an object, this protocol allows that object to be automatically saved and loaded in EZLists and EZDicts.
ezarr-1.0.0/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # eZarr
2
+
3
+ Easily store any Python object inside [zarr](https://zarr.readthedocs.io/en/latest/) hierarchies.
4
+ This package defines proxies for regular Python lists (EZList) and dicts (EZDict), built as wrappers around zarr Arrays and Groups.
5
+ It also defines a Protocol for writing and loading any object in zarr hierarchies.
6
+
7
+ ## EZList
8
+ An EZlist is a proxy for a Python list built on top of a zarr.Array.
9
+ It allows storing mixed arbitrary objects in a 1 dimensional sequence.
10
+
11
+ ### Examples
12
+ ```python
13
+ >>> from ezarr import EZList
14
+ >>> from pathlib import Path
15
+
16
+ # EZList creation from a zarr.Array:
17
+ >>> EZList(zarr.array([1, 2, 3]))
18
+ EZList[1, 2, 3]
19
+
20
+ # EZList creation from a list:
21
+ >>> data = [1, "some text", Path("some/path.txt")]
22
+ >>> ez_list = EZList.from_list(data, store={}, name="data")
23
+ # ~~ ~~~~ a name for the list inside the store
24
+ # |
25
+ # or any zarr StoreLike object to store the list
26
+
27
+ >>> ez_list
28
+ EZList[1, 'some text', PosixPath('some/path.txt')]
29
+
30
+ # EZLists support general list methods:
31
+ >>> ez_list[0]
32
+ 1
33
+
34
+ >>> del ez_list[1]
35
+ >>> ez_list
36
+ EZList[1, PosixPath('some/path.txt')]
37
+
38
+ >>> ez_list.append(3.14)
39
+ >>> ez_list
40
+ EZList[1, PosixPath('some/path.txt'), 3.14]
41
+
42
+ >>> ez_list.insert(0, [1, 2, 3])
43
+ >>> ez_list
44
+ EZList[[1, 2, 3], 1, PosixPath('/some/path.txt'), 3.14]
45
+
46
+ # EZList save to zarr store:
47
+ >>> ez_list.save("path/to/store", name="saved_list")
48
+
49
+ # EZList load from zarr store:
50
+ >>> EZList.open("path/to/store", name="saved_list")
51
+ EZList[[1, 2, 3], 1, PosixPath('/some/path.txt'), 3.14]
52
+
53
+ # EZList conversion to a regular list:
54
+ >>> ez_list.copy()
55
+ [[1, 2, 3], 1, PosixPath('some/path.txt'), 3.14]
56
+ ```
57
+
58
+ ## EZDict
59
+ An EZDict is a proxy for a Python dict built on top of a zarr.Group.
60
+ It expands zarr.Groups to store and retrieve arbitrary objects.
61
+
62
+ ### Examples
63
+ ```python
64
+ >>> from ezarr import EZDict
65
+
66
+ # EZdDct creation for a zarr.Group:
67
+ >>> EZDict(zarr.open_group({}))
68
+ EZDict{}
69
+
70
+ # EZDict creation for a dict:
71
+ >>> data = {"a": 1, "b": [1, 2, 3], "c": {"d": "some text"}}
72
+ >>> ez_dict = EZDict.from_dict(data, store={})
73
+ # ~~ or any zarr StoreLike object to store the dict into # |
74
+
75
+ # EZDict lazy representation:
76
+ >>> ez_dict
77
+ EZDict{
78
+ a: 1,
79
+ b: [1 2 3],
80
+ c: {...} # <-- note the nested dict was not loaded for the representation
81
+ }
82
+
83
+ # EZDict save to zarr store:
84
+ >>> ez_dict.save("path/to/store", name="saved_dict")
85
+
86
+ # EZDict load from zarr store:
87
+ >>> EZDict.open("path/to/store", name="saved_dict")
88
+ EZDict{
89
+ a: 1,
90
+ b: [1 2 3],
91
+ c: {...}
92
+ }
93
+
94
+ # EZDict conversion to a regular dict:
95
+ >>> ez_dict.copy()
96
+ {'a': np.int64(1), 'b': array([1, 2, 3]), 'c': {'d': np.str_('some text')}}
97
+
98
+ ```
99
+
100
+ ## SupportsEZReadWrite
101
+ The `SupportsEZReadWrite` protocol, once implemented on an object, allows it to be store in and retrieved from a zarr hierarchy.
102
+
103
+ ```python
104
+ @runtime_checkable
105
+ class SupportsEZRead(Protocol):
106
+ @classmethod
107
+ def __ez_read__(cls, grp: zarr.Group) -> Self: ...
108
+
109
+
110
+ @runtime_checkable
111
+ class SupportsEZWrite(Protocol):
112
+ def __ez_write__(self, grp: zarr.Group) -> None: ...
113
+
114
+
115
+ @runtime_checkable
116
+ class SupportsEZReadWrite(SupportsEZRead, SupportsEZWrite, Protocol): ...
117
+ ```
118
+
119
+ This protocol has 2 parts:
120
+ - `SupportsEZRead` defines the classmethod `__ez_read__(cls, grp: zarr.Group) -> Self` for reconstructing an object from a zarr.Group.
121
+ - `SupportsEZWrite` defines the method `__ez_write__(self, grp: zarr.Group) -> None` for storing an object in a zarr.Group.
122
+
123
+ Once implemented on an object, this protocol allows that object to be automatically saved and loaded in EZLists and EZDicts.
@@ -0,0 +1,5 @@
1
+ from ezarr.dict import EZDict
2
+ from ezarr.list import EZList
3
+ from ezarr.types import PyObject, PyObjectCodec
4
+
5
+ __all__ = ["EZList", "EZDict", "PyObject", "PyObjectCodec"]
@@ -0,0 +1,84 @@
1
+ import itertools as it
2
+ import math
3
+ from typing import Any, cast
4
+
5
+ import numpy as np
6
+ import numpy.typing as npt
7
+ import zarr # pyright: ignore[reportMissingTypeStubs]
8
+
9
+ import ezarr
10
+
11
+
12
+ def repr_element(elem: Any, prefix: str = "") -> str:
13
+ if isinstance(elem, np.str_):
14
+ return f"'{elem}'"
15
+
16
+ if isinstance(elem, np.generic):
17
+ return str(elem)
18
+
19
+ if isinstance(elem, zarr.Group | ezarr.EZDict):
20
+ return "{...}" if len(elem) else "{}" # pyright: ignore[reportUnknownArgumentType]
21
+
22
+ if isinstance(elem, zarr.Array):
23
+ return repr_array(elem, prefix=prefix)
24
+
25
+ return repr(elem)
26
+
27
+
28
+ def repr_array(arr: zarr.Array, prefix: str = "") -> str:
29
+ if arr.size == 0:
30
+ return "[]"
31
+
32
+ if arr.ndim == 0:
33
+ return repr_element(arr[()])
34
+
35
+ data = cast(npt.NDArray[Any], arr.get_orthogonal_selection(tuple(_get_index(shape) for shape in arr.shape)))
36
+
37
+ if np.issubdtype(data.dtype, np.integer):
38
+ align = math.ceil(math.log10(data.max()))
39
+
40
+ elif np.issubdtype(data.dtype, np.floating):
41
+ data = np.vectorize(np.format_float_positional)(data)
42
+ align = np.vectorize(len)(data).max()
43
+
44
+ else:
45
+ data = data.astype(str)
46
+ align = np.vectorize(len)(data)
47
+
48
+ return _print3(data, list(arr.shape), align=align, prefix=prefix, ignore_prefix=True)
49
+
50
+
51
+ def _get_index(axis_shape: int) -> list[int]:
52
+ if axis_shape <= 6:
53
+ return list(range(axis_shape))
54
+
55
+ return [0, 1, 2, -3, -2, -1]
56
+
57
+
58
+ def _print3(data: np.ndarray, shape: list[int], align: int, *, prefix: str = "", ignore_prefix: bool = False) -> str:
59
+ if data.ndim == 1:
60
+ if shape[0] <= 6:
61
+ values = data
62
+ else:
63
+ values = it.chain(data[:3], ["..."], data[3:])
64
+
65
+ return f"{'' if ignore_prefix else prefix}[{' '.join(map(lambda v: f'{v:>{align}}', values))}]"
66
+
67
+ if shape[0] <= 6:
68
+ rows = [
69
+ _print3(data[idx], shape[1:], align, prefix=prefix + " ", ignore_prefix=idx == 0) for idx in range(shape[0])
70
+ ]
71
+
72
+ else:
73
+ rows = [
74
+ _print3(data[0], shape[1:], align, prefix=prefix + " ", ignore_prefix=True),
75
+ _print3(data[1], shape[1:], align, prefix=prefix + " "),
76
+ _print3(data[2], shape[1:], align, prefix=prefix + " "),
77
+ f"{prefix} ...",
78
+ _print3(data[3], shape[1:], align, prefix=prefix + " "),
79
+ _print3(data[4], shape[1:], align, prefix=prefix + " "),
80
+ _print3(data[5], shape[1:], align, prefix=prefix + " "),
81
+ ]
82
+
83
+ sep = "," + "\n" * max(1, len(shape) - 1)
84
+ return f"{'' if ignore_prefix else prefix}[{sep.join(rows)}]"
@@ -0,0 +1,264 @@
1
+ from __future__ import annotations
2
+
3
+ import itertools as it
4
+ from collections.abc import ItemsView, Iterator, Mapping, MutableMapping
5
+ from typing import Any, Self, cast, override
6
+ import warnings
7
+
8
+ import numpy as np
9
+ import numpy.typing as npt
10
+ import zarr
11
+ from numpy._typing import _SupportsArray as SupportsArray # pyright: ignore[reportPrivateUsage]
12
+ from zarr.errors import UnstableSpecificationWarning
13
+ from zarr.storage import StoreLike # pyright: ignore[reportUnknownVariableType]
14
+
15
+ import ezarr
16
+ from ezarr import io
17
+ from ezarr._repr import repr_element
18
+ from ezarr.names import AccessModeLiteral
19
+ from ezarr.object import EZObject
20
+
21
+ type DictData[T] = Mapping[str, int | float | np.integer | np.floating | list[Any] | npt.ArrayLike | DictData[T]]
22
+ type GroupItems = ItemsView[str, zarr.Group | zarr.Array]
23
+
24
+
25
+ class EZDict[T](EZObject[T, dict[str, T]], MutableMapping[str, T]):
26
+ """
27
+ Dict-like object wrapping a zarr.Group for storing arbitrary Python objects
28
+
29
+ Args:
30
+ group: a zarr.Group
31
+
32
+ Example:
33
+ >>> EZDict(zarr.open_group({}))
34
+ EZDict{}
35
+ """
36
+
37
+ def __init__(self, group: zarr.Group) -> None:
38
+ self._group: zarr.Group = group
39
+
40
+ @classmethod
41
+ def from_dict(
42
+ cls,
43
+ dct: Mapping[str, Any],
44
+ *,
45
+ name: str = "",
46
+ store: StoreLike | None = None,
47
+ mode: AccessModeLiteral = "a",
48
+ path: str | None = None,
49
+ overwrite: bool = False,
50
+ ) -> Self:
51
+ r"""
52
+ Create an EZDict from a regular in-memory Python dictionary.
53
+
54
+ Args:
55
+ dct: dictionary with arbitrary data to store.
56
+ name: name for the EZDict, to use inside the store.
57
+ store: Store or path to directory in file system or nam of zip file.
58
+ mode: Persistence mode, in ['r', 'r+', 'a', 'w', 'w-'].
59
+ path: Group path within store.
60
+ overwrite: overwrite object if a group with name `name` already exists ? (default: False)
61
+
62
+ Example:
63
+ >>> data = {"a": 1, "b": [1, 2, 3], "c": {"d": "some text"}}
64
+ >>> ez_dict = EZDict.from_dict(data)
65
+ >>> repr(ez_dict)
66
+ 'EZDict{\n\ta: 1,\n\tb: [1 2 3],\n\tc: {...}\n}'
67
+ """
68
+ if store is None:
69
+ store = {}
70
+
71
+ grp = zarr.open_group(store, mode=mode, path=path)
72
+
73
+ if name:
74
+ grp = grp.create_group(name, overwrite=overwrite)
75
+
76
+ to_visit: list[tuple[Any, str, str]] = [(dct[k], k, "") for k in dct.keys()]
77
+
78
+ while len(to_visit):
79
+ value, name_, path_ = to_visit.pop()
80
+
81
+ if isinstance(value, Mapping):
82
+ to_visit.extend([(value[k], k, f"{path_}/{name_}" if path_ else name_) for k in value.keys()]) # pyright: ignore[reportUnknownArgumentType, reportUnknownVariableType]
83
+
84
+ elif isinstance(value, list | SupportsArray):
85
+ grp.require_group(path_).create_array(name_, data=np.asarray(value), overwrite=overwrite) # pyright: ignore[reportUnknownArgumentType]
86
+
87
+ else:
88
+ io.write_object(grp, obj=value, name=name_, path=path_, overwrite=overwrite)
89
+
90
+ return cls(grp)
91
+
92
+ @staticmethod
93
+ def _repr(grp: zarr.Group) -> str:
94
+ if not len(grp):
95
+ return "{}"
96
+
97
+ if len(grp) > 100:
98
+ return (
99
+ "{\n\t"
100
+ + ",\n\t".join(
101
+ [
102
+ f"{name}: {repr_element(io.read_object(grp, name=name), prefix=f'\t{" " * len(name)} ')}"
103
+ for name in it.islice(sorted(grp.keys()), 0, 10)
104
+ ]
105
+ )
106
+ + ",\n\t...,\n\t"
107
+ + ",\n\t".join(
108
+ [
109
+ f"{name}: {repr_element(io.read_object(grp, name=name), prefix=f'\t{" " * len(name)} ')}"
110
+ for name in it.islice(sorted(grp.keys()), len(grp) - 10, None)
111
+ ]
112
+ )
113
+ + "}"
114
+ )
115
+
116
+ return (
117
+ "{\n\t"
118
+ + ",\n\t".join(
119
+ [
120
+ f"{name}: {repr_element(io.read_object(grp, name=name), prefix=f'\t{" " * len(name)} ')}"
121
+ for name in sorted(grp.keys())
122
+ ]
123
+ )
124
+ + "\n}"
125
+ )
126
+
127
+ @override
128
+ def __repr__(self) -> str:
129
+ return f"{type(self).__name__}{self._repr(self._group)}"
130
+
131
+ @override
132
+ def __len__(self) -> int:
133
+ return len(self._group)
134
+
135
+ @override
136
+ def __getitem__(self, key: str, /) -> T:
137
+ return io.read_object(self._group, name=key)
138
+
139
+ @override
140
+ def __setitem__(self, key: str, value: T, /) -> None:
141
+ if key in self:
142
+ try:
143
+ # try to compare values, might fail when comparing arrays with different shapes
144
+ if self[key] == value:
145
+ return
146
+
147
+ except ValueError:
148
+ pass
149
+
150
+ with warnings.catch_warnings(action="ignore", category=UnstableSpecificationWarning):
151
+ io.write_object(self._group, obj=value, name=key, overwrite=True)
152
+
153
+ @override
154
+ def __delitem__(self, key: str, /) -> None:
155
+ del self._group[key]
156
+
157
+ @override
158
+ def __iter__(self) -> Iterator[str]:
159
+ yield from sorted(self._group.keys())
160
+
161
+ def __deepcopy__(self, _memo: dict[Any, Any]) -> dict[str, Any]:
162
+ return self.copy()
163
+
164
+ def __ior__(self, other: object) -> EZDict[T]:
165
+ if not isinstance(other, Mapping):
166
+ raise NotImplementedError
167
+
168
+ other = cast(Mapping[str, T], other)
169
+ for name, value in other.items():
170
+ if isinstance(value, Mapping):
171
+ grp = self._group.require_group(name)
172
+ EZDict(grp).__ior__(value) # pyright: ignore[reportUnknownArgumentType]
173
+
174
+ else:
175
+ with warnings.catch_warnings(action="ignore", category=UnstableSpecificationWarning):
176
+ self[name] = value
177
+
178
+ return self
179
+
180
+ @classmethod
181
+ @override
182
+ def open(
183
+ cls, store: StoreLike | None = None, *, name: str = "", mode: AccessModeLiteral = "a", path: str | None = None
184
+ ) -> Self:
185
+ r"""
186
+ Open this EZDict from a store.
187
+
188
+ Args:
189
+ store: Store, path to a directory or name of a zip file.
190
+ name: name for the EZDict, to use inside the store.
191
+ mode: Persistence mode.
192
+ path: path within the store to open.
193
+
194
+ Example:
195
+ >>> ez_dict = EZDict.from_dict({"a": 1, "b": [1, 2, 3], "c": {"d": "some text"}})
196
+ >>> ez_dict.save("/tmp/dict", overwrite=True)
197
+ >>> repr(ez_dict.open("/tmp/dict"))
198
+ 'EZDict{\n\ta: 1,\n\tb: [1 2 3]\n}'
199
+ """
200
+ path = f"{path.rstrip('/')}/{name}" if path else name
201
+ return cls(zarr.open_group(store, mode=mode, path=path))
202
+
203
+ @override
204
+ def save(
205
+ self,
206
+ store: StoreLike,
207
+ *,
208
+ name: str = "",
209
+ mode: AccessModeLiteral = "a",
210
+ path: str | None = None,
211
+ overwrite: bool = False,
212
+ ) -> None:
213
+ """
214
+ Save this EZDict to a local file system.
215
+
216
+ Args:
217
+ store: Store, path to a directory or name of a zip file.
218
+ name: name for the EZDict, to use inside the store.
219
+ mode: Persistence mode.
220
+ path: path within the store where the EZDict will be saved.
221
+ overwrite: overwrite EZDict if a group with name `name` already exists ? (default: False)
222
+
223
+ Example:
224
+ >>> from pathlib import Path
225
+ >>> ez_dict = EZDict.from_dict({"a": 1, "b": [1, 2, 3], "c": {"d": "some text"}})
226
+ >>> ez_dict.save("/tmp/dict", overwrite=True)
227
+ >>> Path("/tmp/dict").exists()
228
+ True
229
+ """
230
+ path = f"{path.rstrip('/')}/{name}/" if path else f"{name}/"
231
+
232
+ for _, array in self._group.arrays():
233
+ assert isinstance(array, zarr.Array)
234
+ zarr.create_array(store, name=path + array.path, data=array, overwrite=overwrite) # pyright: ignore[reportArgumentType]
235
+
236
+ @staticmethod
237
+ def _copy_nested(dct: dict[str, Any], value: EZDict[Any]) -> dict[str, Any]:
238
+ for k, v in value.items():
239
+ if isinstance(v, EZDict):
240
+ sub = dct.setdefault(k, {})
241
+ EZDict._copy_nested(sub, v) # pyright: ignore[reportUnknownArgumentType]
242
+
243
+ elif isinstance(v, ezarr.EZList):
244
+ dct[k] = v.copy()
245
+
246
+ elif isinstance(v, zarr.Array):
247
+ dct[k] = np.array(v)
248
+
249
+ else:
250
+ dct[k] = v
251
+
252
+ return dct
253
+
254
+ @override
255
+ def copy(self) -> dict[str, T]:
256
+ """
257
+ Convert this EZDict into a Python dict, loading all the data into memory.
258
+
259
+ Example:
260
+ >>> ez_dict = EZDict.from_dict({"a": 1, "b": [1, 2, 3], "c": {"d": "some text"}})
261
+ >>> ez_dict.copy()
262
+ {'a': np.int64(1), 'b': array([1, 2, 3]), 'c': {'d': np.str_('some text')}}
263
+ """
264
+ return EZDict._copy_nested({}, self)