Skip to content

Commit f2a8222

Browse files
authored
Merge pull request #94 from bcdev/forman-93-return_num_slices
Return the number of slices processed
2 parents 2b7ce32 + 76f257e commit f2a8222

File tree

8 files changed

+39
-18
lines changed

8 files changed

+39
-18
lines changed

CHANGES.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
## Version 0.7.1 (in development)
22

3-
* Fixed link to _slice sources_ in documentation main page.
3+
* The function `zappend.api.zappend()` now returns the number of slices
4+
processed. (#93)
45

56
* Moved all project configuration to `pyproject.toml` and removed
67
`setup.cfg` and requirements files. (#88)
78

9+
* Fixed link to _slice sources_ in documentation main page.
10+
811
## Version 0.7.0 (from 2024-03-19)
912

1013
* Made writing custom slice sources easier and more flexible: (#82)

docs/guide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ zappend(os.listdir("inputs"),
7474
dry_run=True)
7575
```
7676

77-
This remainder of this guide explains the how to use the various `zappend`
77+
The remainder of this guide explains the how to use the various `zappend`
7878
[configuration](config.md) settings.
7979

8080
!!! note

tests/test_api.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ def drop_tsm(slice_ds: xr.Dataset) -> xr.Dataset:
177177

178178
target_dir = "memory://target.zarr"
179179
slices = [make_test_dataset(index=3 * i) for i in range(3)]
180-
zappend(slices, target_dir=target_dir, slice_source=drop_tsm)
180+
count = zappend(slices, target_dir=target_dir, slice_source=drop_tsm)
181+
self.assertEqual(3, count)
181182
ds = xr.open_zarr(target_dir)
182183
self.assertEqual({"time": 9, "y": 50, "x": 100}, ds.sizes)
183184
self.assertEqual({"chl"}, set(ds.data_vars))
@@ -196,7 +197,8 @@ def drop_tsm(slice_ds: xr.Dataset) -> xr.Dataset:
196197

197198
target_dir = "memory://target.zarr"
198199
slices = [make_test_dataset(index=3 * i) for i in range(3)]
199-
zappend(slices, target_dir=target_dir, slice_source=drop_tsm)
200+
count = zappend(slices, target_dir=target_dir, slice_source=drop_tsm)
201+
self.assertEqual(3, count)
200202
ds = xr.open_zarr(target_dir)
201203
self.assertEqual({"time": 9, "y": 50, "x": 100}, ds.sizes)
202204
self.assertEqual({"chl"}, set(ds.data_vars))
@@ -218,7 +220,8 @@ def crop_ds(slice_ds: xr.Dataset) -> xr.Dataset:
218220

219221
target_dir = "memory://target.zarr"
220222
slices = [make_test_dataset(index=3 * i) for i in range(3)]
221-
zappend(slices, target_dir=target_dir, slice_source=crop_ds)
223+
count = zappend(slices, target_dir=target_dir, slice_source=crop_ds)
224+
self.assertEqual(3, count)
222225
ds = xr.open_zarr(target_dir)
223226
self.assertEqual({"time": 9, "y": 40, "x": 90}, ds.sizes)
224227
self.assertEqual({"chl", "tsm"}, set(ds.data_vars))
@@ -258,9 +261,10 @@ def crop_ds(slice_ds: xr.Dataset) -> xr.Dataset:
258261

259262
target_dir = "memory://target.zarr"
260263
slices = [make_test_dataset(index=3 * i) for i in range(3)]
261-
zappend(
264+
count = zappend(
262265
slices, target_dir=target_dir, slice_source=crop_ds, variables=variables
263266
)
267+
self.assertEqual(3, count)
264268
ds = xr.open_zarr(target_dir)
265269
self.assertEqual({"time": 9, "y": 40, "x": 90}, ds.sizes)
266270
self.assertEqual({"chl", "tsm"}, set(ds.data_vars))
@@ -274,7 +278,8 @@ def crop_ds(slice_ds: xr.Dataset) -> xr.Dataset:
274278
def test_some_slices_with_inc_append_step(self):
275279
target_dir = "memory://target.zarr"
276280
slices = [make_test_dataset(index=i, shape=(1, 50, 100)) for i in range(3)]
277-
zappend(slices, target_dir=target_dir, append_step="1D")
281+
count = zappend(slices, target_dir=target_dir, append_step="1D")
282+
self.assertEqual(3, count)
278283
ds = xr.open_zarr(target_dir)
279284
np.testing.assert_array_equal(
280285
ds.time.values,
@@ -293,7 +298,8 @@ def test_some_slices_with_dec_append_step(self):
293298
slices = [
294299
make_test_dataset(index=i, shape=(1, 50, 100)) for i in reversed(range(3))
295300
]
296-
zappend(slices, target_dir=target_dir, append_step="-1D")
301+
count = zappend(slices, target_dir=target_dir, append_step="-1D")
302+
self.assertEqual(3, count)
297303
ds = xr.open_zarr(target_dir)
298304
np.testing.assert_array_equal(
299305
ds.time.values,
@@ -416,7 +422,7 @@ def test_some_slices_with_dec_append_labels(self):
416422
def test_dynamic_attrs_with_one_slice(self):
417423
target_dir = "memory://target.zarr"
418424
slices = [make_test_dataset()]
419-
zappend(
425+
count = zappend(
420426
slices,
421427
target_dir=target_dir,
422428
permit_eval=True,
@@ -426,6 +432,7 @@ def test_dynamic_attrs_with_one_slice(self):
426432
"time_coverage_end": "{{ ds.time[-1] }}",
427433
},
428434
)
435+
self.assertEqual(1, count)
429436
ds = xr.open_zarr(target_dir)
430437
self.assertEqual(
431438
{

tests/test_cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def test_some_slices_and_target(self):
6666
"memory://slice-3.zarr",
6767
],
6868
)
69-
self.assertEqual("", result.output)
69+
self.assertEqual("3 slice datasets processed.\n", result.output)
7070
self.assertEqual(0, result.exit_code)
7171
self.assertTrue(FileObj("memory://target.zarr").exists())
7272

@@ -88,7 +88,7 @@ def test_some_slices_and_target_dry_run(self):
8888
"memory://slice-3.zarr",
8989
],
9090
)
91-
self.assertEqual("", result.output)
91+
self.assertEqual("3 slice datasets processed.\n", result.output)
9292
self.assertEqual(0, result.exit_code)
9393
self.assertFalse(FileObj("memory://target.zarr").exists())
9494

zappend/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
# Permissions are hereby granted under the terms of the MIT License:
33
# https://opensource.org/licenses/MIT.
44

5-
__version__ = "0.8.0.dev0"
5+
__version__ = "0.7.1.dev0"

zappend/api.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def zappend(
3434
slices: Iterable[Any],
3535
config: ConfigLike = None,
3636
**kwargs: Any,
37-
):
37+
) -> int:
3838
"""Robustly create or update a Zarr dataset from dataset slices.
3939
4040
The `zappend` function concatenates the dataset slices from given
@@ -62,11 +62,16 @@ def zappend(
6262
Args:
6363
slices: An iterable that yields slice items.
6464
config: Processor configuration.
65-
May be a file path or URI, a `dict`, `None`, or a sequence of
65+
Can be a file path or URI, a `dict`, `None`, or a sequence of
6666
the aforementioned. If a sequence is used, subsequent
6767
configurations are incremental to the previous ones.
6868
kwargs: Additional configuration parameters.
6969
Can be used to pass or override configuration values in *config*.
70+
71+
Returns:
72+
The number of slices processed. The value can be useful if \
73+
the number of items in `slices` is unknown.
74+
7075
"""
7176
processor = Processor(config, **kwargs)
72-
processor.process_slices(slices)
77+
return processor.process_slices(slices)

zappend/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,14 @@ def zappend(
9393

9494
# noinspection PyBroadException
9595
try:
96-
zappend(
96+
count = zappend(
9797
slices,
9898
config=config,
9999
target_dir=target,
100100
force_new=force_new,
101101
dry_run=dry_run,
102102
)
103+
click.echo(f"{count} slice dataset{'s' if count != 1 else ''} processed.")
103104
except BaseException as e:
104105
if traceback:
105106
import traceback as tb

zappend/processor.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,21 @@ def __init__(self, config: ConfigLike = None, **kwargs):
5858
self._config = _config
5959
self._profiler = Profiler(_config.profiling)
6060

61-
def process_slices(self, slices: Iterable[SliceItem]):
61+
def process_slices(self, slices: Iterable[SliceItem]) -> int:
6262
"""Process the given `slices`.
6363
Passes each slice in `slices` to the `process_slice()` method.
6464
6565
Args:
6666
slices: Iterable of slice items.
67+
Returns:
68+
The number of slices processed.
6769
"""
70+
slice_index = 0
6871
with self._profiler:
69-
for slice_index, slice_item in enumerate(slices):
72+
for slice_item in slices:
7073
self.process_slice(slice_item, slice_index=slice_index)
74+
slice_index += 1
75+
return slice_index
7176

7277
def process_slice(self, slice_item: SliceItem, slice_index: int = 0):
7378
"""Process a single slice item *slice_item*.

0 commit comments

Comments
 (0)