Skip to content

Commit 7e315b5

Browse files
authored
Merge pull request #36 from nlesc-nano/repr
ENH: Improve the `repr` of the various `h5py.File` views
2 parents d8549bd + cdc9f62 commit 7e315b5

File tree

7 files changed

+65
-44
lines changed

7 files changed

+65
-44
lines changed

.github/workflows/pythonpackage.yml

+16-14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
22
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
33

4-
name: Build
4+
name: Tests
55

66
on:
77
push:
88
branches:
99
- master
1010
pull_request:
11+
workflow_dispatch:
12+
13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
15+
cancel-in-progress: true
16+
17+
defaults:
18+
run:
19+
shell: bash
1120

1221
jobs:
1322
build:
@@ -27,20 +36,14 @@ jobs:
2736
special: '; no-optional'
2837
version: '3.10'
2938
steps:
30-
- name: Cancel Previous Runs
31-
uses: styfle/cancel-workflow-action@0.9.1
32-
with:
33-
access_token: ${{ github.token }}
34-
35-
- uses: actions/checkout@v2
39+
- uses: actions/checkout@v3
3640

3741
- name: Set up Python ${{ matrix.version }} on ${{ matrix.os }}
38-
uses: actions/setup-python@v2
42+
uses: actions/setup-python@v3
3943
with:
4044
python-version: ${{ matrix.version }}
4145

4246
- name: Install dependencies
43-
shell: bash
4447
run: |
4548
case "${{ matrix.special }}" in
4649
"; no-optional")
@@ -60,7 +63,6 @@ jobs:
6063
run: pip list
6164

6265
- name: Test with pytest
63-
shell: bash
6466
run: |
6567
case "${{ matrix.special }}" in
6668
"; no-optional")
@@ -78,12 +80,12 @@ jobs:
7880
Linting:
7981
runs-on: ubuntu-latest
8082
steps:
81-
- uses: actions/checkout@v2
83+
- uses: actions/checkout@v3
8284

83-
- name: Set up Python 3.9 on ubuntu-latest
84-
uses: actions/setup-python@v2
85+
- name: Set up Python 3.10 on ubuntu-latest
86+
uses: actions/setup-python@v3
8587
with:
86-
python-version: 3.9
88+
python-version: "3.10"
8789

8890
- name: Install linters
8991
run: |

CHANGELOG.rst

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ All notable changes to this project will be documented in this file.
66
This project adheres to `Semantic Versioning <http://semver.org/>`_.
77

88

9+
2.3.2
10+
*****
11+
* Improve the ``repr`` of the various ``h5py.File`` views.
12+
13+
914
2.3.1
1015
*****
1116
* Allow ``VersionInfo.from_str`` to take any pep 440-compatible version string.

README.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323

2424
################
25-
Nano-Utils 2.3.1
25+
Nano-Utils 2.3.2
2626
################
2727
Utility functions used throughout the various nlesc-nano repositories.
2828

nanoutils/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""The **Nano-Utils** version."""
22

3-
__version__ = '2.3.0'
3+
__version__ = '2.3.2'

nanoutils/_user_dict.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def _reconstruct(cls: type[_ST1], dct: dict[_KT, _VT_co]) -> _ST1:
104104
"""Alternative constructor without argument validation."""
105105
self = cls.__new__(cls)
106106
self._dict = dct
107-
return self # type: ignore[no-any-return]
107+
return self
108108

109109
def __reduce__(self: _ST1) -> tuple[
110110
Callable[[dict[_KT, _VT_co]], _ST1],
@@ -302,7 +302,7 @@ def update(self, __iterable: None | _DictLike[_KT, _VT] = None, **kwargs: _VT) -
302302
if __iterable is None:
303303
self._dict.update(**kwargs)
304304
else:
305-
self._dict.update(__iterable, **kwargs) # type: ignore[arg-type]
305+
self._dict.update(__iterable, **kwargs)
306306

307307
if sys.version_info >= (3, 9):
308308
def __ior__(self: _ST2, other: Mapping[_KT, _VT]) -> _ST2:

nanoutils/hdf5_utils.py

+38-24
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import sys
2222
import abc
23+
import io
2324
from collections import Counter
2425
from collections.abc import Generator, MappingView, Iterator
2526
from typing import NoReturn
@@ -84,6 +85,28 @@ def _iter_dfs(
8485
else:
8586
yield v.name, v
8687

88+
def __repr__(self) -> str:
89+
"""Implement :func:`repr(self) <repr>`."""
90+
cls = type(self)
91+
indent = " " * (3 + len(cls.__name__))
92+
iterator = iter(self)
93+
94+
stream = io.StringIO()
95+
stream.write(f"<{cls.__name__} [")
96+
97+
# Print size-1 view on a single line by special casing the first element
98+
try:
99+
item = next(iterator)
100+
except StopIteration:
101+
pass
102+
else:
103+
stream.write(repr(item))
104+
for item in iterator:
105+
stream.write(f",\n{indent}{item!r}")
106+
107+
stream.write("]>")
108+
return stream.getvalue()
109+
87110
def __len__(self) -> int:
88111
"""Implement :func:`len(self)<len>`."""
89112
i = 0
@@ -150,14 +173,11 @@ class RecursiveKeysView(_RecursiveMappingView, KeysView[str]):
150173
... dset1 = f.create_dataset('dset1', (10,), dtype=float)
151174
... dset2 = f['a'].create_dataset('dset2', (10,), dtype=float)
152175
... dset3 = f['a']['b'].create_dataset('dset3', (10,), dtype=float)
153-
154-
>>> with h5py.File(filename, 'r') as f:
155-
... for key in RecursiveKeysView(f):
156-
... print(repr(key))
157-
'/a/b/dset3'
158-
'/a/dset2'
159-
'/dset1'
160-
176+
...
177+
... print(RecursiveKeysView(f))
178+
<RecursiveKeysView ['/a/b/dset3',
179+
'/a/dset2',
180+
'/dset1']>
161181
162182
.. testcleanup:: python
163183
@@ -223,14 +243,11 @@ class RecursiveValuesView(_RecursiveMappingView, ValuesView[H5PyDataset]):
223243
... dset1 = f.create_dataset('dset1', (10,), dtype=float)
224244
... dset2 = f['a'].create_dataset('dset2', (10,), dtype=float)
225245
... dset3 = f['a']['b'].create_dataset('dset3', (10,), dtype=float)
226-
227-
>>> with h5py.File(filename, 'r') as f:
228-
... for value in RecursiveValuesView(f):
229-
... print(value)
230-
<HDF5 dataset "dset3": shape (10,), type "<f8">
231-
<HDF5 dataset "dset2": shape (10,), type "<f8">
232-
<HDF5 dataset "dset1": shape (10,), type "<f8">
233-
246+
...
247+
... print(RecursiveValuesView(f))
248+
<RecursiveValuesView [<HDF5 dataset "dset3": shape (10,), type "<f8">,
249+
<HDF5 dataset "dset2": shape (10,), type "<f8">,
250+
<HDF5 dataset "dset1": shape (10,), type "<f8">]>
234251
235252
.. testcleanup:: python
236253
@@ -303,14 +320,11 @@ class RecursiveItemsView(_RecursiveMappingView, ItemsView[str, H5PyDataset]):
303320
... dset1 = f.create_dataset('dset1', (10,), dtype=float)
304321
... dset2 = f['a'].create_dataset('dset2', (10,), dtype=float)
305322
... dset3 = f['a']['b'].create_dataset('dset3', (10,), dtype=float)
306-
307-
>>> with h5py.File(filename, 'r') as f:
308-
... for items in RecursiveItemsView(f):
309-
... print(items)
310-
('/a/b/dset3', <HDF5 dataset "dset3": shape (10,), type "<f8">)
311-
('/a/dset2', <HDF5 dataset "dset2": shape (10,), type "<f8">)
312-
('/dset1', <HDF5 dataset "dset1": shape (10,), type "<f8">)
313-
323+
...
324+
... print(RecursiveItemsView(f))
325+
<RecursiveItemsView [('/a/b/dset3', <HDF5 dataset "dset3": shape (10,), type "<f8">),
326+
('/a/dset2', <HDF5 dataset "dset2": shape (10,), type "<f8">),
327+
('/dset1', <HDF5 dataset "dset1": shape (10,), type "<f8">)]>
314328
315329
.. testcleanup:: python
316330

nanoutils/utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ def _keep_keys(
350350
return [k for k in dct if k not in keep_keys]
351351
else:
352352
try:
353-
return dct.keys() - keep_keys # type: ignore
353+
return dct.keys() - keep_keys
354354
except TypeError:
355355
return set(dct.keys()).difference(keep_keys)
356356

@@ -365,7 +365,7 @@ def _disgard_keys(
365365
return [k for k in dct if k in keep_keys]
366366
else:
367367
try:
368-
return dct.keys() & keep_keys # type: ignore
368+
return dct.keys() & keep_keys
369369
except TypeError:
370370
return set(dct.keys()).intersection(keep_keys)
371371

0 commit comments

Comments
 (0)