Skip to content

Commit a7ca643

Browse files
committed
ENH: improved error message on invalid getitem key (closes #1101)
1 parent 7bf1afc commit a7ca643

File tree

3 files changed

+71
-4
lines changed

3 files changed

+71
-4
lines changed

doc/source/changes/version_0_34_3.rst.inc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,40 @@ New features
77
* added support for Python 3.12 (closes :issue:`1109`).
88

99

10+
Miscellaneous improvements
11+
^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
* improved the error message when selecting several labels at the same time and some of them were wrong.
14+
In that case, it was hard to know which labels were wrong. This was especially annoying if the axis was long and
15+
thus not shown in its entirety in the error message. For example, given the following array: ::
16+
17+
>>> arr = la.ndtest('a=a0,a1;b=b0..b2,b4..b7')
18+
>>> arr
19+
a\b b0 b1 b2 b4 b5 b6 b7
20+
a0 0 1 2 3 4 5 6
21+
a1 7 8 9 10 11 12 13
22+
23+
This code: ::
24+
25+
>>> arr['b0,b2,b3,b7']
26+
27+
used to produce the following error: ::
28+
29+
ValueError: 'b0,b2,b3,b7' is not a valid label for any axis:
30+
a [2]: 'a0' 'a1'
31+
b [7]: 'b0' 'b1' 'b2' ... 'b5' 'b6' 'b7'
32+
33+
which did not contain enough information to determine the problem was with 'b3'. It now produces this instead: ::
34+
35+
ValueError: 'b0,b2,b3,b7' is not a valid subset for any axis:
36+
a [2]: 'a0' 'a1'
37+
b [7]: 'b0' 'b1' 'b2' ... 'b5' 'b6' 'b7'
38+
Some of those labels are valid though:
39+
* axis 'b' contains 3 out of 4 labels (missing labels: 'b3')
40+
41+
Closes :issue:`1101`.
42+
43+
1044
Fixes
1145
^^^^^
1246

larray/core/axis.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2681,7 +2681,38 @@ def _translate_nice_key(self, axis_key):
26812681
except KeyError:
26822682
continue
26832683
if not valid_axes:
2684-
raise ValueError(f"{axis_key!r} is not a valid label for any axis:\n{self._axes_summary()}")
2684+
# if the key has several labels
2685+
nicer_key = _to_key(axis_key)
2686+
sequence_types = (tuple, list, np.ndarray, ABCArray)
2687+
if (isinstance(nicer_key, sequence_types) or
2688+
(isinstance(nicer_key, Group) and isinstance(nicer_key.key, sequence_types))):
2689+
2690+
# we use a different "base" message in this case (because axis_key is not really a *label*)
2691+
msg = f"{axis_key!r} is not a valid subset for any axis:\n{self._axes_summary()}"
2692+
2693+
# ... and check for partial matches
2694+
if isinstance(nicer_key, Group):
2695+
nicer_key = nicer_key.eval()
2696+
key_label_set = set(nicer_key)
2697+
partial_matches = {}
2698+
for axis in self:
2699+
missing_labels = key_label_set - set(axis.labels)
2700+
if missing_labels < key_label_set:
2701+
partial_matches[axis] = missing_labels
2702+
2703+
if partial_matches:
2704+
partial_matches_str = '\n'.join(
2705+
f" * axis '{self.axis_id(axis)}' contains {len(key_label_set) - len(missing_labels)}"
2706+
f' out of {len(key_label_set)}'
2707+
f' labels (missing labels: {", ".join(repr(label) for label in missing_labels)})'
2708+
for axis, missing_labels in partial_matches.items()
2709+
)
2710+
msg += f"\nSome of those labels are valid though:\n{partial_matches_str}"
2711+
else:
2712+
# we have single label
2713+
msg = f"{axis_key!r} is not a valid label for any axis:\n{self._axes_summary()}"
2714+
2715+
raise ValueError(msg)
26852716
elif len(valid_axes) > 1:
26862717
raise ValueError(f'{axis_key!r} is ambiguous, it is valid in the following axes:\n'
26872718
f'{self._axes_summary(valid_axes)}')

larray/tests/test_array.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ def test_getitem_guess_axis(array):
664664
_ = array[[1, 2], 999]
665665

666666
# key with invalid label list (ie list of labels not found on any axis)
667-
with must_raise(ValueError, """[998, 999] is not a valid label for any axis:
667+
with must_raise(ValueError, """[998, 999] is not a valid subset for any axis:
668668
a [19]: 0 1 2 ... 16 17 18
669669
b [12]: 'b0' 'b1' 'b2' ... 'b10' 'b11' 'b3'
670670
c [2]: 'c0' 'c1'
@@ -678,11 +678,13 @@ def test_getitem_guess_axis(array):
678678
"7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18"):
679679
_ = array[[1, 2], [3, 999]]
680680

681-
with must_raise(ValueError, """[999, 4] is not a valid label for any axis:
681+
with must_raise(ValueError, """[999, 4] is not a valid subset for any axis:
682682
a [19]: 0 1 2 ... 16 17 18
683683
b [12]: 'b0' 'b1' 'b2' ... 'b10' 'b11' 'b3'
684684
c [2]: 'c0' 'c1'
685-
d [6]: 'd1' 'd2' 'd3' 'd4' 'd5' 'd6'"""):
685+
d [6]: 'd1' 'd2' 'd3' 'd4' 'd5' 'd6'
686+
Some of those labels are valid though:
687+
* axis 'a' contains 1 out of 2 labels (missing labels: 999)"""):
686688
_ = array[[1, 2], [999, 4]]
687689

688690
# ambiguous key

0 commit comments

Comments
 (0)