@@ -34,8 +34,9 @@ cdef inline int int_min(int a, int b): return a if a <= b else b
34
34
35
35
cdef class SparseIndex:
36
36
"""
37
- Abstract superclass for sparse index types
37
+ Abstract superclass for sparse index types.
38
38
"""
39
+
39
40
def __init__ (self ):
40
41
raise NotImplementedError
41
42
@@ -48,8 +49,9 @@ cdef class IntIndex(SparseIndex):
48
49
----------
49
50
length : integer
50
51
indices : array-like
51
- Contains integers corresponding to
52
+ Contains integers corresponding to the indices.
52
53
"""
54
+
53
55
cdef readonly:
54
56
Py_ssize_t length, npoints
55
57
ndarray indices
@@ -59,9 +61,11 @@ cdef class IntIndex(SparseIndex):
59
61
self .indices = np.ascontiguousarray(indices, dtype = np.int32)
60
62
self .npoints = len (self .indices)
61
63
64
+ self .check_integrity()
65
+
62
66
def __reduce__ (self ):
63
67
args = (self .length, self .indices)
64
- return ( IntIndex, args)
68
+ return IntIndex, args
65
69
66
70
def __repr__ (self ):
67
71
output = ' IntIndex\n '
@@ -70,10 +74,40 @@ cdef class IntIndex(SparseIndex):
70
74
71
75
def check_integrity (self ):
72
76
"""
73
- Only need be strictly ascending and nothing less than 0 or greater than
74
- total length
77
+ Checks the following:
78
+
79
+ - Indices are strictly ascending
80
+ - Number of indices is at most self.length
81
+ - Indices are at least 0 and at most the total length less one
82
+
83
+ A ValueError is raised if any of these conditions is violated.
75
84
"""
76
- pass
85
+
86
+ cdef:
87
+ int32_t index, prev = - 1
88
+
89
+ if self .npoints > self .length:
90
+ msg = (" Too many indices. Expected "
91
+ " {exp} but found {act}" ).format(
92
+ exp = self .length, act = self .npoints)
93
+ raise ValueError (msg)
94
+
95
+ # Indices are vacuously ordered and non-negative
96
+ # if the sequence of indices is empty.
97
+ if self .npoints == 0 :
98
+ return
99
+
100
+ if min (self .indices) < 0 :
101
+ raise ValueError (" No index can be less than zero" )
102
+
103
+ if max (self .indices) >= self .length:
104
+ raise ValueError (" All indices must be less than the length" )
105
+
106
+ for index in self .indices:
107
+ if prev != - 1 and index <= prev:
108
+ raise ValueError (" Indices must be strictly increasing" )
109
+
110
+ prev = index
77
111
78
112
def equals (self , other ):
79
113
if not isinstance (other, IntIndex):
@@ -320,7 +354,7 @@ cdef class BlockIndex(SparseIndex):
320
354
321
355
def __reduce__ (self ):
322
356
args = (self .length, self .blocs, self .blengths)
323
- return ( BlockIndex, args)
357
+ return BlockIndex, args
324
358
325
359
def __repr__ (self ):
326
360
output = ' BlockIndex\n '
0 commit comments