forked from zarr-developers/zarr-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharray_spec.py
122 lines (97 loc) · 3.55 KB
/
array_spec.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from __future__ import annotations
from dataclasses import dataclass, fields
from typing import TYPE_CHECKING, Any, Literal, Self, TypedDict, cast
import numpy as np
from zarr.core.common import (
MemoryOrder,
parse_bool,
parse_fill_value,
parse_order,
parse_shapelike,
)
from zarr.core.config import config as zarr_config
if TYPE_CHECKING:
from typing import NotRequired
from zarr.core.buffer import BufferPrototype
from zarr.core.common import ChunkCoords
class ArrayConfigParams(TypedDict):
"""
A TypedDict model of the attributes of an ArrayConfig class, but with no required fields.
This allows for partial construction of an ArrayConfig, with the assumption that the unset
keys will be taken from a global configuration.
"""
order: NotRequired[MemoryOrder]
write_empty_chunks: NotRequired[bool]
@dataclass(frozen=True)
class ArrayConfig:
"""
A model of the runtime configuration of an array.
Parameters
----------
order : MemoryOrder
The memory layout of the arrays returned when reading data from the store.
write_empty_chunks : bool
If True, empty chunks will be written to the store.
"""
order: MemoryOrder
write_empty_chunks: bool
def __init__(self, order: MemoryOrder, write_empty_chunks: bool) -> None:
order_parsed = parse_order(order)
write_empty_chunks_parsed = parse_bool(write_empty_chunks)
object.__setattr__(self, "order", order_parsed)
object.__setattr__(self, "write_empty_chunks", write_empty_chunks_parsed)
@classmethod
def from_dict(cls, data: ArrayConfigParams) -> Self:
"""
Create an ArrayConfig from a dict. The keys of that dict are a subset of the
attributes of the ArrayConfig class. Any keys missing from that dict will be set to the
the values in the ``array`` namespace of ``zarr.config``.
"""
kwargs_out: ArrayConfigParams = {}
for f in fields(ArrayConfig):
field_name = cast(Literal["order", "write_empty_chunks"], f.name)
if field_name not in data:
kwargs_out[field_name] = zarr_config.get(f"array.{field_name}")
else:
kwargs_out[field_name] = data[field_name]
return cls(**kwargs_out)
ArrayConfigLike = ArrayConfig | ArrayConfigParams
def parse_array_config(data: ArrayConfigLike | None) -> ArrayConfig:
"""
Convert various types of data to an ArrayConfig.
"""
if data is None:
return ArrayConfig.from_dict({})
elif isinstance(data, ArrayConfig):
return data
else:
return ArrayConfig.from_dict(data)
@dataclass(frozen=True)
class ArraySpec:
shape: ChunkCoords
dtype: np.dtype[Any]
fill_value: Any
config: ArrayConfig
prototype: BufferPrototype
def __init__(
self,
shape: ChunkCoords,
dtype: np.dtype[Any],
fill_value: Any,
config: ArrayConfig,
prototype: BufferPrototype,
) -> None:
shape_parsed = parse_shapelike(shape)
dtype_parsed = np.dtype(dtype)
fill_value_parsed = parse_fill_value(fill_value)
object.__setattr__(self, "shape", shape_parsed)
object.__setattr__(self, "dtype", dtype_parsed)
object.__setattr__(self, "fill_value", fill_value_parsed)
object.__setattr__(self, "config", config)
object.__setattr__(self, "prototype", prototype)
@property
def ndim(self) -> int:
return len(self.shape)
@property
def order(self) -> MemoryOrder:
return self.config.order