1
1
from __future__ import annotations
2
2
3
3
import json
4
- from typing import TYPE_CHECKING
4
+ from typing import TYPE_CHECKING , Any
5
5
6
6
import numpy as np
7
7
import pytest
10
10
import zarr .api .asynchronous
11
11
import zarr .api .synchronous
12
12
import zarr .storage
13
+ from zarr import AsyncGroup
13
14
from zarr .api .asynchronous import (
14
- AsyncGroup ,
15
15
consolidate_metadata ,
16
16
group ,
17
17
open ,
27
27
28
28
if TYPE_CHECKING :
29
29
from zarr .abc .store import Store
30
- from zarr .core .common import ZarrFormat
30
+ from zarr .core .common import JSON , ZarrFormat
31
31
32
32
33
33
@pytest .fixture
34
- async def memory_store_with_hierarchy (memory_store : Store ) -> None :
34
+ async def memory_store_with_hierarchy (memory_store : Store ) -> Store :
35
35
g = await group (store = memory_store , attributes = {"foo" : "bar" })
36
36
dtype = "uint8"
37
37
await g .create_array (name = "air" , shape = (1 , 2 , 3 ), dtype = dtype )
@@ -51,15 +51,15 @@ async def memory_store_with_hierarchy(memory_store: Store) -> None:
51
51
52
52
53
53
class TestConsolidated :
54
- async def test_open_consolidated_false_raises (self ):
54
+ async def test_open_consolidated_false_raises (self ) -> None :
55
55
store = zarr .storage .MemoryStore ()
56
56
with pytest .raises (TypeError , match = "use_consolidated" ):
57
- await zarr .api .asynchronous .open_consolidated (store , use_consolidated = False )
57
+ await zarr .api .asynchronous .open_consolidated (store , use_consolidated = False ) # type: ignore[arg-type]
58
58
59
- def test_open_consolidated_false_raises_sync (self ):
59
+ def test_open_consolidated_false_raises_sync (self ) -> None :
60
60
store = zarr .storage .MemoryStore ()
61
61
with pytest .raises (TypeError , match = "use_consolidated" ):
62
- zarr .open_consolidated (store , use_consolidated = False )
62
+ zarr .open_consolidated (store , use_consolidated = False ) # type: ignore[arg-type]
63
63
64
64
async def test_consolidated (self , memory_store_with_hierarchy : Store ) -> None :
65
65
# TODO: Figure out desired keys in
@@ -75,7 +75,7 @@ async def test_consolidated(self, memory_store_with_hierarchy: Store) -> None:
75
75
await consolidate_metadata (memory_store_with_hierarchy )
76
76
group2 = await AsyncGroup .open (memory_store_with_hierarchy )
77
77
78
- array_metadata = {
78
+ array_metadata : dict [ str , JSON ] = {
79
79
"attributes" : {},
80
80
"chunk_key_encoding" : {
81
81
"configuration" : {"separator" : "/" },
@@ -192,13 +192,12 @@ async def test_consolidated(self, memory_store_with_hierarchy: Store) -> None:
192
192
group4 = await open_consolidated (store = memory_store_with_hierarchy )
193
193
assert group4 .metadata == expected
194
194
195
- result_raw = json .loads (
196
- (
197
- await memory_store_with_hierarchy .get (
198
- "zarr.json" , prototype = default_buffer_prototype ()
199
- )
200
- ).to_bytes ()
201
- )["consolidated_metadata" ]
195
+ buf = await memory_store_with_hierarchy .get (
196
+ "zarr.json" , prototype = default_buffer_prototype ()
197
+ )
198
+ assert buf is not None
199
+
200
+ result_raw = json .loads (buf .to_bytes ())["consolidated_metadata" ]
202
201
assert result_raw ["kind" ] == "inline"
203
202
assert sorted (result_raw ["metadata" ]) == [
204
203
"air" ,
@@ -212,7 +211,7 @@ async def test_consolidated(self, memory_store_with_hierarchy: Store) -> None:
212
211
"time" ,
213
212
]
214
213
215
- def test_consolidated_sync (self , memory_store ) :
214
+ def test_consolidated_sync (self , memory_store : Store ) -> None :
216
215
g = zarr .api .synchronous .group (store = memory_store , attributes = {"foo" : "bar" })
217
216
dtype = "uint8"
218
217
g .create_array (name = "air" , shape = (1 , 2 , 3 ), dtype = dtype )
@@ -225,9 +224,9 @@ def test_consolidated_sync(self, memory_store):
225
224
match = "Consolidated metadata is currently not part in the Zarr format 3 specification." ,
226
225
):
227
226
zarr .api .synchronous .consolidate_metadata (memory_store )
228
- group2 = zarr .api . synchronous . Group .open (memory_store )
227
+ group2 = zarr .Group .open (memory_store )
229
228
230
- array_metadata = {
229
+ array_metadata : dict [ str , JSON ] = {
231
230
"attributes" : {},
232
231
"chunk_key_encoding" : {
233
232
"configuration" : {"separator" : "/" },
@@ -320,8 +319,8 @@ async def test_non_root_node(self, memory_store_with_hierarchy: Store) -> None:
320
319
assert "air" not in child .metadata .consolidated_metadata .metadata
321
320
assert "grandchild" in child .metadata .consolidated_metadata .metadata
322
321
323
- def test_consolidated_metadata_from_dict (self ):
324
- data = {"must_understand" : False }
322
+ def test_consolidated_metadata_from_dict (self ) -> None :
323
+ data : dict [ str , JSON ] = {"must_understand" : False }
325
324
326
325
# missing kind
327
326
with pytest .raises (ValueError , match = "kind='None'" ):
@@ -343,8 +342,8 @@ def test_consolidated_metadata_from_dict(self):
343
342
data ["metadata" ] = {}
344
343
ConsolidatedMetadata .from_dict (data )
345
344
346
- def test_flatten (self ):
347
- array_metadata = {
345
+ def test_flatten (self ) -> None :
346
+ array_metadata : dict [ str , Any ] = {
348
347
"attributes" : {},
349
348
"chunk_key_encoding" : {
350
349
"configuration" : {"separator" : "/" },
@@ -421,27 +420,28 @@ def test_flatten(self):
421
420
},
422
421
)
423
422
result = metadata .flattened_metadata
423
+
424
424
expected = {
425
425
"air" : metadata .metadata ["air" ],
426
426
"lat" : metadata .metadata ["lat" ],
427
427
"child" : GroupMetadata (
428
428
attributes = {"key" : "child" }, consolidated_metadata = ConsolidatedMetadata (metadata = {})
429
429
),
430
- "child/array" : metadata .metadata ["child" ].consolidated_metadata .metadata ["array" ],
430
+ "child/array" : metadata .metadata ["child" ].consolidated_metadata .metadata ["array" ], # type: ignore[union-attr]
431
431
"child/grandchild" : GroupMetadata (
432
432
attributes = {"key" : "grandchild" },
433
433
consolidated_metadata = ConsolidatedMetadata (metadata = {}),
434
434
),
435
435
"child/grandchild/array" : (
436
436
metadata .metadata ["child" ]
437
- .consolidated_metadata .metadata ["grandchild" ]
437
+ .consolidated_metadata .metadata ["grandchild" ] # type: ignore[union-attr]
438
438
.consolidated_metadata .metadata ["array" ]
439
439
),
440
440
}
441
441
assert result == expected
442
442
443
- def test_invalid_metadata_raises (self ):
444
- payload = {
443
+ def test_invalid_metadata_raises (self ) -> None :
444
+ payload : dict [ str , JSON ] = {
445
445
"kind" : "inline" ,
446
446
"must_understand" : False ,
447
447
"metadata" : {
@@ -452,7 +452,7 @@ def test_invalid_metadata_raises(self):
452
452
with pytest .raises (TypeError , match = "key='foo', type='list'" ):
453
453
ConsolidatedMetadata .from_dict (payload )
454
454
455
- def test_to_dict_empty (self ):
455
+ def test_to_dict_empty (self ) -> None :
456
456
meta = ConsolidatedMetadata (
457
457
metadata = {
458
458
"empty" : GroupMetadata (
@@ -507,6 +507,7 @@ async def test_to_dict_order(
507
507
await zarr .api .asynchronous .consolidate_metadata (memory_store )
508
508
g2 = await zarr .api .asynchronous .open_group (store = memory_store )
509
509
510
+ assert g2 .metadata .consolidated_metadata is not None
510
511
assert list (g2 .metadata .consolidated_metadata .metadata ) == ["a" , "b" , "c" ]
511
512
assert list (g2 .metadata .consolidated_metadata .flattened_metadata ) == [
512
513
"a" ,
@@ -517,7 +518,7 @@ async def test_to_dict_order(
517
518
]
518
519
519
520
@pytest .mark .parametrize ("zarr_format" , [2 , 3 ])
520
- async def test_open_consolidated_raises_async (self , zarr_format : ZarrFormat ):
521
+ async def test_open_consolidated_raises_async (self , zarr_format : ZarrFormat ) -> None :
521
522
store = zarr .storage .MemoryStore ()
522
523
await AsyncGroup .from_store (store , zarr_format = zarr_format )
523
524
with pytest .raises (ValueError ):
@@ -535,12 +536,15 @@ async def v2_consolidated_metadata_empty_dataset(
535
536
b'{"metadata":{".zgroup":{"zarr_format":2}},"zarr_consolidated_format":1}'
536
537
)
537
538
return AsyncGroup ._from_bytes_v2 (
538
- None , zgroup_bytes , zattrs_bytes = None , consolidated_metadata_bytes = zmetadata_bytes
539
+ StorePath (memory_store , path = "" ),
540
+ zgroup_bytes ,
541
+ zattrs_bytes = None ,
542
+ consolidated_metadata_bytes = zmetadata_bytes ,
539
543
)
540
544
541
545
async def test_consolidated_metadata_backwards_compatibility (
542
- self , v2_consolidated_metadata_empty_dataset
543
- ):
546
+ self , v2_consolidated_metadata_empty_dataset : AsyncGroup
547
+ ) -> None :
544
548
"""
545
549
Test that consolidated metadata handles a missing .zattrs key. This is necessary for backwards compatibility with zarr-python 2.x. See https://github.com/zarr-developers/zarr-python/issues/2694
546
550
"""
@@ -550,7 +554,7 @@ async def test_consolidated_metadata_backwards_compatibility(
550
554
result = await zarr .api .asynchronous .open_consolidated (store , zarr_format = 2 )
551
555
assert result .metadata == v2_consolidated_metadata_empty_dataset .metadata
552
556
553
- async def test_consolidated_metadata_v2 (self ):
557
+ async def test_consolidated_metadata_v2 (self ) -> None :
554
558
store = zarr .storage .MemoryStore ()
555
559
g = await AsyncGroup .from_store (store , attributes = {"key" : "root" }, zarr_format = 2 )
556
560
dtype = parse_dtype ("uint8" , zarr_format = 2 )
@@ -638,7 +642,9 @@ async def test_use_consolidated_false(
638
642
assert good .metadata .consolidated_metadata
639
643
assert sorted (good .metadata .consolidated_metadata .metadata ) == ["a" , "b" ]
640
644
641
- async def test_stale_child_metadata_ignored (self , memory_store : zarr .storage .MemoryStore ):
645
+ async def test_stale_child_metadata_ignored (
646
+ self , memory_store : zarr .storage .MemoryStore
647
+ ) -> None :
642
648
# https://github.com/zarr-developers/zarr-python/issues/2921
643
649
# When consolidating metadata, we should ignore any (possibly stale) metadata
644
650
# from previous consolidations, *including at child nodes*.
@@ -660,7 +666,7 @@ async def test_stale_child_metadata_ignored(self, memory_store: zarr.storage.Mem
660
666
661
667
async def test_use_consolidated_for_children_members (
662
668
self , memory_store : zarr .storage .MemoryStore
663
- ):
669
+ ) -> None :
664
670
# A test that has *unconsolidated* metadata at the root group, but discovers
665
671
# a child group with consolidated metadata.
666
672
@@ -690,7 +696,7 @@ async def test_use_consolidated_for_children_members(
690
696
@pytest .mark .parametrize ("fill_value" , [np .nan , np .inf , - np .inf ])
691
697
async def test_consolidated_metadata_encodes_special_chars (
692
698
memory_store : Store , zarr_format : ZarrFormat , fill_value : float
693
- ):
699
+ ) -> None :
694
700
root = await group (store = memory_store , zarr_format = zarr_format )
695
701
_time = await root .create_array ("time" , shape = (12 ,), dtype = np .float64 , fill_value = fill_value )
696
702
if zarr_format == 3 :
@@ -728,7 +734,7 @@ def supports_consolidated_metadata(self) -> bool:
728
734
return False
729
735
730
736
731
- async def test_consolidate_metadata_raises_for_self_consolidating_stores ():
737
+ async def test_consolidate_metadata_raises_for_self_consolidating_stores () -> None :
732
738
"""Verify calling consolidate_metadata on a non supporting stores raises an error."""
733
739
734
740
memory_store = NonConsolidatedStore ()
@@ -739,7 +745,7 @@ async def test_consolidate_metadata_raises_for_self_consolidating_stores():
739
745
await zarr .api .asynchronous .consolidate_metadata (memory_store )
740
746
741
747
742
- async def test_open_group_in_non_consolidating_stores ():
748
+ async def test_open_group_in_non_consolidating_stores () -> None :
743
749
memory_store = NonConsolidatedStore ()
744
750
root = await zarr .api .asynchronous .create_group (store = memory_store )
745
751
await root .create_group ("a/b" )
0 commit comments