4
4
import json
5
5
import os
6
6
import struct
7
- import warnings
8
- from collections .abc import Iterable
7
+ from collections .abc import Hashable , Iterable , Mapping
9
8
from typing import TYPE_CHECKING , Any , Literal
10
9
11
10
import numpy as np
46
45
from xarray .core .datatree import DataTree
47
46
48
47
48
+ def _get_mappers (* , storage_options , store , chunk_store ):
49
+ # expand str and path-like arguments
50
+ store = _normalize_path (store )
51
+ chunk_store = _normalize_path (chunk_store )
52
+
53
+ kwargs = {}
54
+ if storage_options is None :
55
+ mapper = store
56
+ chunk_mapper = chunk_store
57
+ else :
58
+ if not isinstance (store , str ):
59
+ raise ValueError (
60
+ f"store must be a string to use storage_options. Got { type (store )} "
61
+ )
62
+
63
+ if _zarr_v3 ():
64
+ kwargs ["storage_options" ] = storage_options
65
+ mapper = store
66
+ chunk_mapper = chunk_store
67
+ else :
68
+ from fsspec import get_mapper
69
+
70
+ mapper = get_mapper (store , ** storage_options )
71
+ if chunk_store is not None :
72
+ chunk_mapper = get_mapper (chunk_store , ** storage_options )
73
+ else :
74
+ chunk_mapper = chunk_store
75
+ return kwargs , mapper , chunk_mapper
76
+
77
+
78
+ def _choose_default_mode (
79
+ * ,
80
+ mode : ZarrWriteModes | None ,
81
+ append_dim : Hashable | None ,
82
+ region : Mapping [str , slice | Literal ["auto" ]] | Literal ["auto" ] | None ,
83
+ ) -> ZarrWriteModes :
84
+ if mode is None :
85
+ if append_dim is not None :
86
+ mode = "a"
87
+ elif region is not None :
88
+ mode = "r+"
89
+ else :
90
+ mode = "w-"
91
+
92
+ if mode not in ["a" , "a-" ] and append_dim is not None :
93
+ raise ValueError ("cannot set append_dim unless mode='a' or mode=None" )
94
+
95
+ if mode not in ["a" , "a-" , "r+" ] and region is not None :
96
+ raise ValueError (
97
+ "cannot set region unless mode='a', mode='a-', mode='r+' or mode=None"
98
+ )
99
+
100
+ if mode not in ["w" , "w-" , "a" , "a-" , "r+" ]:
101
+ raise ValueError (
102
+ "The only supported options for mode are 'w', "
103
+ f"'w-', 'a', 'a-', and 'r+', but mode={ mode !r} "
104
+ )
105
+ return mode
106
+
107
+
49
108
def _zarr_v3 () -> bool :
50
109
# TODO: switch to "3" once Zarr V3 is released
51
110
return module_available ("zarr" , minversion = "2.99" )
@@ -567,7 +626,6 @@ def open_store(
567
626
append_dim = None ,
568
627
write_region = None ,
569
628
safe_chunks = True ,
570
- stacklevel = 2 ,
571
629
zarr_version = None ,
572
630
zarr_format = None ,
573
631
use_zarr_fill_value_as_mask = None ,
@@ -587,7 +645,6 @@ def open_store(
587
645
consolidate_on_close = consolidate_on_close ,
588
646
chunk_store = chunk_store ,
589
647
storage_options = storage_options ,
590
- stacklevel = stacklevel ,
591
648
zarr_version = zarr_version ,
592
649
use_zarr_fill_value_as_mask = use_zarr_fill_value_as_mask ,
593
650
zarr_format = zarr_format ,
@@ -622,7 +679,6 @@ def open_group(
622
679
append_dim = None ,
623
680
write_region = None ,
624
681
safe_chunks = True ,
625
- stacklevel = 2 ,
626
682
zarr_version = None ,
627
683
zarr_format = None ,
628
684
use_zarr_fill_value_as_mask = None ,
@@ -642,7 +698,6 @@ def open_group(
642
698
consolidate_on_close = consolidate_on_close ,
643
699
chunk_store = chunk_store ,
644
700
storage_options = storage_options ,
645
- stacklevel = stacklevel ,
646
701
zarr_version = zarr_version ,
647
702
use_zarr_fill_value_as_mask = use_zarr_fill_value_as_mask ,
648
703
zarr_format = zarr_format ,
@@ -1105,7 +1160,10 @@ def _auto_detect_regions(self, ds, region):
1105
1160
region [dim ] = slice (idxs [0 ], idxs [- 1 ] + 1 )
1106
1161
return region
1107
1162
1108
- def _validate_and_autodetect_region (self , ds ) -> None :
1163
+ def _validate_and_autodetect_region (self , ds : Dataset ) -> Dataset :
1164
+ if self ._write_region is None :
1165
+ return ds
1166
+
1109
1167
region = self ._write_region
1110
1168
1111
1169
if region == "auto" :
@@ -1153,8 +1211,26 @@ def _validate_and_autodetect_region(self, ds) -> None:
1153
1211
f".drop_vars({ non_matching_vars !r} )"
1154
1212
)
1155
1213
1214
+ if self ._append_dim is not None and self ._append_dim in region :
1215
+ raise ValueError (
1216
+ f"cannot list the same dimension in both ``append_dim`` and "
1217
+ f"``region`` with to_zarr(), got { self ._append_dim } in both"
1218
+ )
1219
+
1156
1220
self ._write_region = region
1157
1221
1222
+ # can't modify indexes with region writes
1223
+ return ds .drop_vars (ds .indexes )
1224
+
1225
+ def _validate_encoding (self , encoding ) -> None :
1226
+ if encoding and self ._mode in ["a" , "a-" , "r+" ]:
1227
+ existing_var_names = set (self .zarr_group .array_keys ())
1228
+ for var_name in existing_var_names :
1229
+ if var_name in encoding :
1230
+ raise ValueError (
1231
+ f"variable { var_name !r} already exists, but encoding was provided"
1232
+ )
1233
+
1158
1234
1159
1235
def open_zarr (
1160
1236
store ,
@@ -1329,7 +1405,6 @@ def open_zarr(
1329
1405
"overwrite_encoded_chunks" : overwrite_encoded_chunks ,
1330
1406
"chunk_store" : chunk_store ,
1331
1407
"storage_options" : storage_options ,
1332
- "stacklevel" : 4 ,
1333
1408
"zarr_version" : zarr_version ,
1334
1409
"zarr_format" : zarr_format ,
1335
1410
}
@@ -1398,7 +1473,6 @@ def open_dataset( # type: ignore[override] # allow LSP violation, not supporti
1398
1473
consolidated = None ,
1399
1474
chunk_store = None ,
1400
1475
storage_options = None ,
1401
- stacklevel = 3 ,
1402
1476
zarr_version = None ,
1403
1477
zarr_format = None ,
1404
1478
store = None ,
@@ -1416,7 +1490,6 @@ def open_dataset( # type: ignore[override] # allow LSP violation, not supporti
1416
1490
consolidate_on_close = False ,
1417
1491
chunk_store = chunk_store ,
1418
1492
storage_options = storage_options ,
1419
- stacklevel = stacklevel + 1 ,
1420
1493
zarr_version = zarr_version ,
1421
1494
use_zarr_fill_value_as_mask = None ,
1422
1495
zarr_format = zarr_format ,
@@ -1453,7 +1526,6 @@ def open_datatree(
1453
1526
consolidated = None ,
1454
1527
chunk_store = None ,
1455
1528
storage_options = None ,
1456
- stacklevel = 3 ,
1457
1529
zarr_version = None ,
1458
1530
zarr_format = None ,
1459
1531
** kwargs ,
@@ -1474,7 +1546,6 @@ def open_datatree(
1474
1546
consolidated = consolidated ,
1475
1547
chunk_store = chunk_store ,
1476
1548
storage_options = storage_options ,
1477
- stacklevel = stacklevel ,
1478
1549
zarr_version = zarr_version ,
1479
1550
zarr_format = zarr_format ,
1480
1551
** kwargs ,
@@ -1499,7 +1570,6 @@ def open_groups_as_dict(
1499
1570
consolidated = None ,
1500
1571
chunk_store = None ,
1501
1572
storage_options = None ,
1502
- stacklevel = 3 ,
1503
1573
zarr_version = None ,
1504
1574
zarr_format = None ,
1505
1575
** kwargs ,
@@ -1523,7 +1593,6 @@ def open_groups_as_dict(
1523
1593
consolidate_on_close = False ,
1524
1594
chunk_store = chunk_store ,
1525
1595
storage_options = storage_options ,
1526
- stacklevel = stacklevel + 1 ,
1527
1596
zarr_version = zarr_version ,
1528
1597
zarr_format = zarr_format ,
1529
1598
)
@@ -1569,7 +1638,6 @@ def _get_open_params(
1569
1638
consolidate_on_close ,
1570
1639
chunk_store ,
1571
1640
storage_options ,
1572
- stacklevel ,
1573
1641
zarr_version ,
1574
1642
use_zarr_fill_value_as_mask ,
1575
1643
zarr_format ,
@@ -1614,7 +1682,7 @@ def _get_open_params(
1614
1682
# ValueError in zarr-python 3.x, KeyError in 2.x.
1615
1683
try :
1616
1684
zarr_group = zarr .open_group (store , ** open_kwargs )
1617
- warnings . warn (
1685
+ emit_user_level_warning (
1618
1686
"Failed to open Zarr store with consolidated metadata, "
1619
1687
"but successfully read with non-consolidated metadata. "
1620
1688
"This is typically much slower for opening a dataset. "
@@ -1627,7 +1695,6 @@ def _get_open_params(
1627
1695
"error in this case instead of falling back to try "
1628
1696
"reading non-consolidated metadata." ,
1629
1697
RuntimeWarning ,
1630
- stacklevel = stacklevel ,
1631
1698
)
1632
1699
except missing_exc as err :
1633
1700
raise FileNotFoundError (
0 commit comments