zarr_metadata.testing.strategies
zarr_metadata.testing ¶
Testing utilities for code that reads or writes Zarr metadata.
zarr_metadata.testing.strategies holds Hypothesis strategies that draw
valid metadata. It needs the testing extra:
pip install zarr-metadata[testing].
zarr_metadata.testing.strategies ¶
Hypothesis strategies for valid Zarr v3 metadata fields.
Every strategy here draws metadata its definition accepts, and that the spec allows: a reader, writer or converter can test itself against the whole space of a codec's, data type's, chunk grid's or chunk key encoding's configurations instead of the handful its authors thought to write down.
from hypothesis import given
from zarr_metadata.testing.strategies import fields
from zarr_metadata.v3.codec.blosc import BLOSC_CODEC
@given(fields(BLOSC_CODEC))
def test_my_reader_reads_every_blosc_codec(field):
my_reader.read_codec(field)
What a configuration depends on, each kind's function takes:
fill_values a data type's configuration, chunk_grid_configurations
the shape of the array, codec_configurations the Chunk the codec is
handed. Left out, nothing is known of it, and what is drawn is what the
definition's rules accept. fields wraps configurations in the
envelopes a document writes them in.
How each definition's configurations are drawn is a value,
Strategies, keyed by the definition: DEFAULT_STRATEGIES holds one
for each definition this package defines that holds no other field. An
extension author adds their own with
DEFAULT_STRATEGIES | {MY_CODEC: CodecStrategy(...)}.
Configurations are drawn at the data level the TypedDicts declare, JSON
arrays as tuples; json.dumps takes them as they are.
Requires the testing extra (pip install zarr-metadata[testing]).
Configurations
module-attribute
¶
Configurations: TypeAlias = (
"SearchStrategy[Mapping[str, JSONValue]]"
)
Configurations of one definition, each the mapping every configuration is.
DEFAULT_STRATEGIES
module-attribute
¶
DEFAULT_STRATEGIES: Final[
MappingProxyType[Definition[Any], DefinitionStrategy]
] = MappingProxyType(
{
**DATA_TYPE_STRATEGIES,
**CHUNK_GRID_STRATEGIES,
**CHUNK_KEY_ENCODING_STRATEGIES,
**CODEC_STRATEGIES,
}
)
A strategy for each definition this package defines that holds no other field.
NOTHING_KNOWN
module-attribute
¶
A chunk nothing is known of, which every codec takes.
Spellings
module-attribute
¶
Spellings = Literal['all', 'canonical']
How fields are written: every spelling the spec allows, or only the simplest.
"all" draws each envelope the spec gives a field -- a bare name, an
object without a configuration, an empty configuration, a
must_understand of true -- and configurations that say what a
simpler one says, as a blosc typesize under noshuffle does.
"canonical" draws each in the spelling canonicalize gives it, which
is what a writer that writes the fewest words writes.
Strategies
module-attribute
¶
Strategies: TypeAlias = Mapping[Any, DefinitionStrategy]
How to draw each definition's configurations, by the definition.
The key is Any, not Definition[Any]: a mapping's key type is
invariant, so {MY_CODEC: CodecStrategy(...)}, a mapping keyed by a
CodecDefinition, would not be a Mapping[Definition[Any], ...].
ChunkGridStrategy
dataclass
¶
Bases: DefinitionStrategy
How to draw a chunk grid's configurations over an array of a shape.
Source code in src/zarr_metadata/testing/_strategy.py
configurations
instance-attribute
¶
configurations: Callable[
[tuple[int, ...] | None], Configurations
]
Configurations of grids that fit an array of the shape.
Handed None, no shape is known, and what is drawn is what the grid's rules accept, whatever shape it is put over.
kind
class-attribute
¶
kind: type[Definition[Any]] = ChunkGridDefinition
The kind of definition it draws configurations of: a chunk grid.
unconstrained ¶
unconstrained() -> Configurations
Configurations when nothing is known of what they depend on: what the definition's rules accept.
ChunkKeyEncodingStrategy
dataclass
¶
Bases: DefinitionStrategy
How to draw a chunk key encoding's configurations.
Source code in src/zarr_metadata/testing/_strategy.py
configurations
instance-attribute
¶
configurations: Configurations
Configurations its definition accepts.
kind
class-attribute
¶
kind: type[Definition[Any]] = ChunkKeyEncodingDefinition
The kind of definition it draws configurations of: a chunk key encoding.
unconstrained ¶
unconstrained() -> Configurations
Configurations when nothing is known of what they depend on: what the definition's rules accept.
CodecStrategy
dataclass
¶
Bases: DefinitionStrategy
How to draw a codec's configurations, handed a chunk.
Every codec takes Chunk(), a chunk nothing is known of, so a
strategy that draws nothing for it is refused when it is built.
Source code in src/zarr_metadata/testing/_strategy.py
configurations
instance-attribute
¶
configurations: Callable[[Chunk], Configurations | None]
Configurations of the codec handed the chunk; None when no configuration takes it.
A bytes codec handed a string chunk is None, since the spec gives
that data type a codec of its own.
kind
class-attribute
¶
kind: type[Definition[Any]] = CodecDefinition
The kind of definition it draws configurations of: a codec.
unconstrained ¶
unconstrained() -> Configurations
Configurations when nothing is known of what they depend on: what the definition's rules accept.
DataTypeStrategy
dataclass
¶
Bases: DefinitionStrategy
How to draw a data type's configurations, and the fill values an array of one takes.
Source code in src/zarr_metadata/testing/_strategy.py
configurations
instance-attribute
¶
configurations: Configurations
Configurations its definition accepts.
fill_values
instance-attribute
¶
Fill values of the data type a configuration describes.
kind
class-attribute
¶
kind: type[Definition[Any]] = DataTypeDefinition
The kind of definition it draws configurations of: a data type.
unconstrained ¶
unconstrained() -> Configurations
Configurations when nothing is known of what they depend on: what the definition's rules accept.
DefinitionStrategy ¶
Bases: ABC
How to draw the configurations of one kind of definition.
Source code in src/zarr_metadata/testing/_strategy.py
kind
class-attribute
¶
kind: type[Definition[Any]]
The kind of definition whose configurations it draws.
unconstrained
abstractmethod
¶
unconstrained() -> Configurations
Configurations when nothing is known of what they depend on: what the definition's rules accept.
chunk_grid_configurations ¶
chunk_grid_configurations(
definition: ChunkGridDefinition[C],
shape: tuple[int, ...] | None = None,
*,
strategies: Strategies = DEFAULT_STRATEGIES,
) -> SearchStrategy[C]
Configurations of the chunk grid definition defines, that fit an array of shape.
With no shape, what is drawn is what the grid's rules accept.
Source code in src/zarr_metadata/testing/strategies.py
chunk_key_encoding_configurations ¶
chunk_key_encoding_configurations(
definition: ChunkKeyEncodingDefinition[C],
*,
strategies: Strategies = DEFAULT_STRATEGIES,
) -> SearchStrategy[C]
Configurations of the chunk key encoding definition defines.
Source code in src/zarr_metadata/testing/strategies.py
codec_configurations ¶
codec_configurations(
definition: CodecDefinition[C],
chunk: Chunk = NOTHING_KNOWN,
*,
strategies: Strategies = DEFAULT_STRATEGIES,
) -> SearchStrategy[C] | None
Configurations of the codec definition defines, handed chunk; None when none takes it.
With no chunk, nothing is known of it, and what is drawn is what the codec's rules accept.
Source code in src/zarr_metadata/testing/strategies.py
data_type_configurations ¶
data_type_configurations(
definition: DataTypeDefinition[C],
*,
strategies: Strategies = DEFAULT_STRATEGIES,
) -> SearchStrategy[C]
Configurations of the data type definition defines.
Source code in src/zarr_metadata/testing/strategies.py
fields ¶
fields(
definition: Definition[C],
configurations: SearchStrategy[C] | UNSET = UNSET,
*,
spellings: Spellings = "all",
strategies: Strategies = DEFAULT_STRATEGIES,
) -> SearchStrategy[ZarrV3MetadataFieldJSON]
Metadata fields of definition: its name and a configuration, in an envelope a document writes.
configurations is what to draw the configuration from, by default
the definition's own with nothing known of what they depend on: pass
codec_configurations(definition, chunk) for a codec handed a chunk,
once it is known not to be None. spellings says whether every
spelling the spec allows is drawn, or only the simplest.
Each field is read in a scope of its definition alone, with no chunk
known, and one its definition's rules refuse, as they refuse one
drawn from configurations they do not accept, raises a
ValueError. A codec's chunk rules are not checked: what fits the
chunk is what codec_configurations draws.
Source code in src/zarr_metadata/testing/strategies.py
fill_values ¶
fill_values(
definition: DataTypeDefinition[C],
configuration: C,
*,
strategies: Strategies = DEFAULT_STRATEGIES,
) -> SearchStrategy[JSONValue]
Fill values of the data type definition and configuration describe, in every spelling the spec gives them.