Skip to content

Commit 36da816

Browse files
HyeockJinKimncw
authored andcommitted
Handle the non-integer return of __index__ - Fixes #96
Generate TypeError when __index__ return non-integer value * Handle error of slice in range type * When an error occurs, the error is returned and * when the value is none the slice's values have a default value. * Add tests for __index__ * Add tests for __index__ function * Add tests for __index__ in list, tuple, string
1 parent f100534 commit 36da816

File tree

6 files changed

+130
-8
lines changed

6 files changed

+130
-8
lines changed

py/internal.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,12 @@ func Index(a Object) (Int, error) {
9595
if err != nil {
9696
return 0, err
9797
}
98+
9899
if res, ok := A.(Int); ok {
99100
return res, nil
100101
}
101102

102-
return 0, err
103+
return 0, ExceptionNewf(TypeError, "__index__ returned non-int: (type %s)", A.Type().Name)
103104
}
104105

105106
return 0, ExceptionNewf(TypeError, "unsupported operand type(s) for index: '%s'", a.Type().Name)

py/range.go

+17-7
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,16 @@ func computeRangeLength(start, stop, step Int) Int {
160160
return res
161161
}
162162

163+
func getIndexWithDefault(i Object, d Int) (Int, error) {
164+
if i == None {
165+
return d, nil
166+
} else if res, err := Index(i); err != nil {
167+
return 0, err
168+
} else {
169+
return res, nil
170+
}
171+
}
172+
163173
func computeNegativeIndex(index, length Int) Int {
164174
if index < 0 {
165175
index += length
@@ -177,19 +187,19 @@ func computeBoundIndex(index, length Int) Int {
177187
}
178188

179189
func computeRangeSlice(r *Range, s *Slice) (Object, error) {
180-
start, err := Index(s.Start)
190+
start, err := getIndexWithDefault(s.Start, 0)
181191
if err != nil {
182-
start = 0
192+
return nil, err
183193
}
184-
stop, err := Index(s.Stop)
194+
stop, err := getIndexWithDefault(s.Stop, r.Length)
185195
if err != nil {
186-
stop = r.Length
196+
return nil, err
187197
}
188-
189-
step, err := Index(s.Step)
198+
step, err := getIndexWithDefault(s.Step, 1)
190199
if err != nil {
191-
step = 1
200+
return nil, err
192201
}
202+
193203
if step == 0 {
194204
return nil, ExceptionNewf(ValueError, "slice step cannot be zero")
195205
}

py/tests/list.py

+30
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,34 @@
113113
assertRaises(TypeError, lambda: list.sort(s5, key=1))
114114
assertRaises(TypeError, lambda: list.sort(1))
115115

116+
class Index:
117+
def __index__(self):
118+
return 1
119+
120+
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
121+
b = Index()
122+
assert a[b] == 1
123+
assert a[b:10] == a[1:10]
124+
assert a[10:b:-1] == a[10:1:-1]
125+
126+
class NonIntegerIndex:
127+
def __index__(self):
128+
return 1.1
129+
130+
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
131+
b = NonIntegerIndex()
132+
try:
133+
a[b]
134+
except TypeError:
135+
pass
136+
else:
137+
assert False, "TypeError not raised"
138+
139+
try:
140+
a[b:10]
141+
except TypeError:
142+
pass
143+
else:
144+
assert False, "TypeError not raised"
145+
116146
doc="finished"

py/tests/range.py

+20
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,24 @@ def __index__(self):
116116
assert a[b:10] == a[1:10]
117117
assert a[10:b:-1] == a[10:1:-1]
118118

119+
class NonIntegerIndex:
120+
def __index__(self):
121+
return 1.1
122+
123+
a = range(10)
124+
b = NonIntegerIndex()
125+
try:
126+
a[b]
127+
except TypeError:
128+
pass
129+
else:
130+
assert False, "TypeError not raised"
131+
132+
try:
133+
a[b:10]
134+
except TypeError:
135+
pass
136+
else:
137+
assert False, "TypeError not raised"
138+
119139
doc="finished"

py/tests/string.py

+31
Original file line numberDiff line numberDiff line change
@@ -886,4 +886,35 @@ def index(s, i):
886886
assert uni[7:7:2] == ''
887887
assert uni[7:7:3] == ''
888888

889+
class Index:
890+
def __index__(self):
891+
return 1
892+
893+
a = '012345678910'
894+
b = Index()
895+
assert a[b] == '1'
896+
assert a[b:10] == a[1:10]
897+
assert a[10:b:-1] == a[10:1:-1]
898+
899+
class NonIntegerIndex:
900+
def __index__(self):
901+
return 1.1
902+
903+
a = '012345678910'
904+
b = NonIntegerIndex()
905+
try:
906+
a[b]
907+
except TypeError:
908+
pass
909+
else:
910+
assert False, "TypeError not raised"
911+
912+
try:
913+
a[b:10]
914+
except TypeError:
915+
pass
916+
else:
917+
assert False, "TypeError not raised"
918+
919+
889920
doc="finished"

py/tests/tuple.py

+30
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,34 @@
2222
assert a * 0 == ()
2323
assert a * -1 == ()
2424

25+
class Index:
26+
def __index__(self):
27+
return 1
28+
29+
a = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
30+
b = Index()
31+
assert a[b] == 1
32+
assert a[b:10] == a[1:10]
33+
assert a[10:b:-1] == a[10:1:-1]
34+
35+
class NonIntegerIndex:
36+
def __index__(self):
37+
return 1.1
38+
39+
a = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
40+
b = NonIntegerIndex()
41+
try:
42+
a[b]
43+
except TypeError:
44+
pass
45+
else:
46+
assert False, "TypeError not raised"
47+
48+
try:
49+
a[b:10]
50+
except TypeError:
51+
pass
52+
else:
53+
assert False, "TypeError not raised"
54+
2555
doc="finished"

0 commit comments

Comments
 (0)