|
19 | 19 | import zarr |
20 | 20 | from icechunk import Repository, Storage, in_memory_storage |
21 | 21 | from icechunk.testing import strategies as icst |
| 22 | +from zarr import Array |
22 | 23 | from zarr.core.buffer import default_buffer_prototype |
23 | 24 | from zarr.storage import MemoryStore |
24 | | -from zarr.testing.stateful import ZarrHierarchyStateMachine |
| 25 | +from zarr.testing.stateful import ZarrHierarchyStateMachine, split_prefix_name |
25 | 26 | from zarr.testing.strategies import ( |
26 | 27 | node_names, |
27 | 28 | np_array_and_chunks, |
@@ -317,6 +318,38 @@ def _compare_list_dir( |
317 | 318 | def check_list_dir(self) -> None: |
318 | 319 | self._compare_list_dir(self.model, self.store, self.all_groups | self.all_arrays) |
319 | 320 |
|
| 321 | + # Override upstream delete_group_using_del to fix precondition bug: |
| 322 | + # upstream checks `len(self.all_groups) >= 2` but filters to only groups |
| 323 | + # with "/" in their path, crashing when only root-level groups remain. |
| 324 | + # Fix: allow deleting any group (root "" is never in all_groups). |
| 325 | + # TODO: remove once https://github.com/zarr-developers/zarr-python/pull/3707 is released |
| 326 | + # and is our minimum required version |
| 327 | + @precondition(lambda self: self.store.supports_deletes) |
| 328 | + @precondition(lambda self: bool(self.all_groups - {"", "/"})) |
| 329 | + @rule(data=st.data()) |
| 330 | + def delete_group_using_del(self, data: st.DataObject) -> None: |
| 331 | + group_path = data.draw( |
| 332 | + st.sampled_from(sorted(self.all_groups - {"", "/"})), |
| 333 | + label="Group deletion target", |
| 334 | + ) |
| 335 | + prefix, group_name = split_prefix_name(group_path) |
| 336 | + note( |
| 337 | + f"Deleting group '{group_path=!r}', {prefix=!r}, {group_name=!r} using delete" |
| 338 | + ) |
| 339 | + members = zarr.open_group(store=self.model, path=group_path).members( |
| 340 | + max_depth=None |
| 341 | + ) |
| 342 | + for _, obj in members: |
| 343 | + if isinstance(obj, Array): |
| 344 | + self.all_arrays.remove(obj.path) |
| 345 | + else: |
| 346 | + self.all_groups.remove(obj.path) |
| 347 | + for store in [self.store, self.model]: |
| 348 | + group = zarr.open_group(store=store, path=prefix) |
| 349 | + group[group_name] # check that it exists |
| 350 | + del group[group_name] |
| 351 | + self.all_groups.remove(group_path) |
| 352 | + |
320 | 353 | @rule() |
321 | 354 | def pickle_objects(self) -> None: |
322 | 355 | if not self.store.session.has_uncommitted_changes: |
|
0 commit comments