Skip to content

Commit 6a25001

Browse files
committed
itemmodels.AbstractSortTableModel: Fix mapFromSourceRows
1 parent 9225e8d commit 6a25001

File tree

2 files changed

+55
-7
lines changed

2 files changed

+55
-7
lines changed

Orange/widgets/utils/itemmodels.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def mapToSourceRows(self, rows):
118118
119119
Parameters
120120
----------
121-
rows : int or list of int or numpy.ndarray or Ellipsis
121+
rows : int or list of int or numpy.ndarray of dtype=int or Ellipsis
122122
View (sorted) rows.
123123
124124
Returns
@@ -127,7 +127,10 @@ def mapToSourceRows(self, rows):
127127
Source rows matching input rows. If they are the same,
128128
simply input `rows` is returned.
129129
"""
130-
if self.__sortInd is not None:
130+
# self.__sortInd[rows] fails if `rows` is an empty list or array
131+
if self.__sortInd is not None \
132+
and (isinstance(rows, (Integral, type(Ellipsis)))
133+
or len(rows)):
131134
new_rows = self.__sortInd[rows]
132135
if rows is Ellipsis:
133136
new_rows.setflags(write=False)
@@ -139,7 +142,7 @@ def mapFromSourceRows(self, rows):
139142
140143
Parameters
141144
----------
142-
rows : int or list of int or numpy.ndarray or Ellipsis
145+
rows : int or list of int or numpy.ndarray of dtype=int or Ellipsis
143146
Source model rows.
144147
145148
Returns
@@ -148,7 +151,10 @@ def mapFromSourceRows(self, rows):
148151
ModelIndex (sorted) rows matching input source rows.
149152
If they are the same, simply input `rows` is returned.
150153
"""
151-
if self.__sortIndInv is not None:
154+
# self.__sortInd[rows] fails if `rows` is an empty list or array
155+
if self.__sortIndInv is not None \
156+
and (isinstance(rows, (Integral, type(Ellipsis)))
157+
or len(rows)):
152158
new_rows = self.__sortIndInv[rows]
153159
if rows is Ellipsis:
154160
new_rows.setflags(write=False)

Orange/widgets/utils/tests/test_itemmodels.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
from unittest import TestCase
55

6+
import numpy as np
7+
68
from AnyQt.QtCore import Qt
79

810
from Orange.data import Domain, ContinuousVariable, DiscreteVariable
@@ -124,14 +126,54 @@ class TestAbstractSortTableModel(TestCase):
124126
def setUp(self):
125127
assert issubclass(PyTableModel, AbstractSortTableModel)
126128
self.model = PyTableModel([[1, 4],
127-
[2, 3]])
129+
[2, 2],
130+
[3, 3]])
128131

129132
def test_sorting(self):
130133
self.model.sort(1, Qt.AscendingOrder)
131-
self.assertSequenceEqual(self.model.mapToSourceRows(...).tolist(), [1, 0])
134+
self.assertSequenceEqual(self.model.mapToSourceRows(...).tolist(), [1, 2, 0])
132135

133136
self.model.sort(1, Qt.DescendingOrder)
134-
self.assertSequenceEqual(self.model.mapToSourceRows(...).tolist(), [0, 1])
137+
self.assertSequenceEqual(self.model.mapToSourceRows(...).tolist(), [0, 2, 1])
138+
139+
def test_mapFromSourceRows(self):
140+
model = self.model
141+
model.sort(1, Qt.AscendingOrder)
142+
self.assertSequenceEqual(model.mapFromSourceRows(...).tolist(), [2, 0, 1])
143+
self.assertSequenceEqual(model.mapFromSourceRows([1, 2]).tolist(), [0, 1])
144+
self.assertSequenceEqual(model.mapFromSourceRows([]), [])
145+
self.assertSequenceEqual(model.mapFromSourceRows(np.array([], dtype=int)), [])
146+
self.assertEqual(model.mapFromSourceRows(1), 0)
147+
148+
def test_mapToSourceRows(self):
149+
# self.model is not appropriate here since it is its own inverse, so the
150+
# test wouldn't check whether the method works in the right direction
151+
model = PyTableModel([[1, 4],
152+
[2, 2],
153+
[3, 3]])
154+
model.sort(1, Qt.AscendingOrder)
155+
self.assertSequenceEqual(model.mapToSourceRows(...).tolist(), [1, 2, 0])
156+
self.assertEqual(model.mapToSourceRows(1).tolist(), 2)
157+
self.assertSequenceEqual(model.mapToSourceRows([1, 2]).tolist(), [2, 0])
158+
self.assertSequenceEqual(model.mapToSourceRows([]), [])
159+
self.assertSequenceEqual(
160+
model.mapToSourceRows(np.array([], dtype=int)).tolist(), [])
161+
162+
163+
def test_mapFromSourceRows(self):
164+
# self.model is not appropriate here since it is its own inverse, so the
165+
# test wouldn't check whether the method works in the right direction
166+
model = PyTableModel([[1, 4],
167+
[2, 2],
168+
[3, 3]])
169+
model.sort(1, Qt.AscendingOrder)
170+
self.assertSequenceEqual(model.mapFromSourceRows(...).tolist(), [2, 0, 1])
171+
self.assertEqual(model.mapFromSourceRows(1).tolist(), 0)
172+
self.assertSequenceEqual(model.mapFromSourceRows([1, 2]).tolist(), [0, 1])
173+
self.assertSequenceEqual(model.mapFromSourceRows([]), [])
174+
self.assertSequenceEqual(
175+
model.mapFromSourceRows(np.array([], dtype=int)).tolist(), [])
176+
self.assertRaises(IndexError, model.mapFromSourceRows, np.r_[0.])
135177

136178

137179
class TestPyListModel(TestCase):

0 commit comments

Comments
 (0)