Skip to content

Commit 44100c8

Browse files
committed
stdlib/array: add support for 'u' arrays
Signed-off-by: Sebastien Binet <binet@cern.ch>
1 parent 53252dd commit 44100c8

File tree

3 files changed

+153
-60
lines changed

3 files changed

+153
-60
lines changed

stdlib/array/array.go

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,12 @@ func array_new(metatype *py.Type, args py.Tuple, kwargs py.StringDict) (py.Objec
197197
esize: descr2esize[descr[0]],
198198
}
199199

200-
if descr[0] == 'u' {
201-
// FIXME(sbinet)
202-
return nil, py.NotImplementedError
203-
}
204-
205200
switch descr[0] {
201+
case 'u':
202+
var data []rune
203+
arr.data = data
204+
arr.append = arr.appendRune
205+
arr.extend = arr.extendRune
206206
case 'b':
207207
var data []int8
208208
arr.data = data
@@ -300,14 +300,21 @@ func (arr *array) M__repr__() (py.Object, error) {
300300
o := new(strings.Builder)
301301
o.WriteString("array('" + string(arr.descr) + "'")
302302
if data := reflect.ValueOf(arr.data); arr.data != nil && data.Len() > 0 {
303-
o.WriteString(", [")
304-
for i := 0; i < data.Len(); i++ {
305-
if i > 0 {
306-
o.WriteString(", ")
303+
switch arr.descr {
304+
case 'u':
305+
o.WriteString(", '")
306+
o.WriteString(string(arr.data.([]rune)))
307+
o.WriteString("'")
308+
default:
309+
o.WriteString(", [")
310+
for i := 0; i < data.Len(); i++ {
311+
if i > 0 {
312+
o.WriteString(", ")
313+
}
314+
fmt.Fprintf(o, "%v", data.Index(i))
307315
}
308-
fmt.Fprintf(o, "%v", data.Index(i))
316+
o.WriteString("]")
309317
}
310-
o.WriteString("]")
311318
}
312319
o.WriteString(")")
313320
return py.String(o.String()), nil
@@ -344,8 +351,7 @@ func (arr *array) M__getitem__(k py.Object) (py.Object, error) {
344351
case 'B', 'H', 'I', 'L', 'Q':
345352
return py.Int(sli.Index(i).Uint()), nil
346353
case 'u':
347-
// FIXME(sbinet)
348-
return nil, py.NotImplementedError
354+
return py.String([]rune{rune(sli.Index(i).Int())}), nil
349355
case 'f', 'd':
350356
return py.Float(sli.Index(i).Float()), nil
351357
}
@@ -372,14 +378,23 @@ func (arr *array) M__setitem__(k, v py.Object) (py.Object, error) {
372378
}
373379
switch arr.descr {
374380
case 'b', 'h', 'i', 'l', 'q':
375-
vv := v.(py.Int)
381+
vv, ok := v.(py.Int)
382+
if !ok {
383+
return nil, py.ExceptionNewf(py.TypeError, "'%s' object cannot be interpreted as an integer", v.Type().Name)
384+
}
376385
sli.Index(i).SetInt(int64(vv))
377386
case 'B', 'H', 'I', 'L', 'Q':
378-
vv := v.(py.Int)
387+
vv, ok := v.(py.Int)
388+
if !ok {
389+
return nil, py.ExceptionNewf(py.TypeError, "'%s' object cannot be interpreted as an integer", v.Type().Name)
390+
}
379391
sli.Index(i).SetUint(uint64(vv))
380392
case 'u':
381-
// FIXME(sbinet)
382-
return nil, py.NotImplementedError
393+
vv, ok := v.(py.Int)
394+
if !ok {
395+
return nil, py.ExceptionNewf(py.TypeError, "array item must be unicode character")
396+
}
397+
sli.Index(i).SetInt(int64(vv))
383398
case 'f', 'd':
384399
var vv float64
385400
switch v := v.(type) {
@@ -401,6 +416,16 @@ func (arr *array) M__setitem__(k, v py.Object) (py.Object, error) {
401416
panic("impossible")
402417
}
403418

419+
func (arr *array) appendRune(v py.Object) (py.Object, error) {
420+
str, ok := v.(py.String)
421+
if !ok {
422+
return nil, py.ExceptionNewf(py.TypeError, "array item must be unicode character")
423+
}
424+
425+
arr.data = append(arr.data.([]rune), []rune(str)...)
426+
return py.None, nil
427+
}
428+
404429
func (arr *array) appendI8(v py.Object) (py.Object, error) {
405430
vv, err := asInt(v)
406431
if err != nil {
@@ -491,6 +516,27 @@ func (arr *array) appendF64(v py.Object) (py.Object, error) {
491516
return py.None, nil
492517
}
493518

519+
func (arr *array) extendRune(arg py.Object) (py.Object, error) {
520+
itr, err := py.Iter(arg)
521+
if err != nil {
522+
return nil, err
523+
}
524+
525+
nxt := itr.(py.I__next__)
526+
527+
for {
528+
o, err := nxt.M__next__()
529+
if err == py.StopIteration {
530+
break
531+
}
532+
_, err = arr.appendRune(o)
533+
if err != nil {
534+
return nil, err
535+
}
536+
}
537+
return py.None, nil
538+
}
539+
494540
func (arr *array) extendI8(arg py.Object) (py.Object, error) {
495541
itr, err := py.Iter(arg)
496542
if err != nil {

stdlib/array/testdata/test.py

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,87 +19,96 @@ def assertEqual(x, y):
1919
print("")
2020
print("typecode '%s'" % (typ,))
2121
if typ == 'u':
22-
# FIXME(sbinet): implement
23-
print(" SKIP: NotImplemented")
24-
continue
22+
arr = array.array(typ, "?世界!")
2523
if typ in "bhilqfd":
2624
arr = array.array(typ, [-1, -2, -3, -4])
2725
if typ in "BHILQ":
2826
arr = array.array(typ, [+1, +2, +3, +4])
29-
print(" array: %s" % (repr(arr),))
27+
print(" array: %s ## repr" % (repr(arr),))
28+
print(" array: %s ## str" % (str(arr),))
3029
print(" itemsize: %s" % (arr.itemsize,))
3130
print(" typecode: %s" % (arr.typecode,))
3231
print(" len: %s" % (len(arr),))
3332
print(" arr[0]: %s" % (arr[0],))
3433
print(" arr[-1]: %s" % (arr[-1],))
3534
try:
3635
arr[-10]
37-
print(" ERROR: expected an exception")
36+
print(" ERROR1: expected an exception")
3837
except:
3938
print(" caught an exception [ok]")
4039

4140
try:
4241
arr[10]
43-
print(" ERROR: expected an exception")
42+
print(" ERROR2: expected an exception")
4443
except:
4544
print(" caught an exception [ok]")
4645
arr[-2] = 33
4746
print(" arr[-2]: %s" % (arr[-2],))
4847

4948
try:
5049
arr[-10] = 2
51-
print(" ERROR: expected an exception")
50+
print(" ERROR3: expected an exception")
5251
except:
5352
print(" caught an exception [ok]")
5453

5554
if typ in "bhilqfd":
5655
arr.extend([-5,-6])
5756
if typ in "BHILQ":
5857
arr.extend([5,6])
58+
if typ == 'u':
59+
arr.extend("he")
5960
print(" array: %s" % (repr(arr),))
6061
print(" len: %s" % (len(arr),))
6162

6263
if typ in "bhilqfd":
6364
arr.append(-7)
6465
if typ in "BHILQ":
6566
arr.append(7)
67+
if typ == 'u':
68+
arr.append("l")
6669
print(" array: %s" % (repr(arr),))
6770
print(" len: %s" % (len(arr),))
6871

6972
try:
7073
arr.append()
71-
print(" ERROR: expected an exception")
74+
print(" ERROR4: expected an exception")
7275
except:
7376
print(" caught an exception [ok]")
7477
try:
7578
arr.append([])
76-
print(" ERROR: expected an exception")
79+
print(" ERROR5: expected an exception")
7780
except:
7881
print(" caught an exception [ok]")
7982
try:
8083
arr.append(1, 2)
81-
print(" ERROR: expected an exception")
84+
print(" ERROR6: expected an exception")
8285
except:
8386
print(" caught an exception [ok]")
8487
try:
8588
arr.append(None)
86-
print(" ERROR: expected an exception")
89+
print(" ERROR7: expected an exception")
8790
except:
8891
print(" caught an exception [ok]")
8992

9093
try:
9194
arr.extend()
92-
print(" ERROR: expected an exception")
95+
print(" ERROR8: expected an exception")
9396
except:
9497
print(" caught an exception [ok]")
9598
try:
9699
arr.extend(None)
97-
print(" ERROR: expected an exception")
100+
print(" ERROR9: expected an exception")
98101
except:
99102
print(" caught an exception [ok]")
100103
try:
101104
arr.extend([1,None])
102-
print(" ERROR: expected an exception")
105+
print(" ERROR10: expected an exception")
106+
except:
107+
print(" caught an exception [ok]")
108+
109+
try:
110+
arr[0] = object()
111+
print(" ERROR11: expected an exception")
103112
except:
104113
print(" caught an exception [ok]")
105114
pass
@@ -108,55 +117,48 @@ def assertEqual(x, y):
108117
print("## testing array.array(...)")
109118
try:
110119
arr = array.array()
111-
print("ERROR: expected an exception")
120+
print("ERROR1: expected an exception")
112121
except:
113122
print("caught an exception [ok]")
114123

115124
try:
116125
arr = array.array(b"d")
117-
print("ERROR: expected an exception")
126+
print("ERROR2: expected an exception")
118127
except:
119128
print("caught an exception [ok]")
120129

121130
try:
122131
arr = array.array("?")
123-
print("ERROR: expected an exception")
132+
print("ERROR3: expected an exception")
124133
except:
125134
print("caught an exception [ok]")
126135

127136
try:
128137
arr = array.array("dd")
129-
print("ERROR: expected an exception")
138+
print("ERROR4: expected an exception")
130139
except:
131140
print("caught an exception [ok]")
132141

133142
try:
134143
arr = array.array("d", initializer=[1,2])
135-
print("ERROR: expected an exception")
144+
print("ERROR5: expected an exception")
136145
except:
137146
print("caught an exception [ok]")
138147

139148
try:
140149
arr = array.array("d", [1], [])
141-
print("ERROR: expected an exception")
150+
print("ERROR6: expected an exception")
142151
except:
143152
print("caught an exception [ok]")
144153

145154
try:
146155
arr = array.array("d", 1)
147-
print("ERROR: expected an exception")
156+
print("ERROR7: expected an exception")
148157
except:
149158
print("caught an exception [ok]")
150159

151160
try:
152161
arr = array.array("d", ["a","b"])
153-
print("ERROR: expected an exception")
154-
except:
155-
print("caught an exception [ok]")
156-
157-
try:
158-
## FIXME(sbinet): implement it at some point.
159-
arr = array.array("u")
160-
print("ERROR: expected an exception")
162+
print("ERROR8: expected an exception")
161163
except:
162164
print("caught an exception [ok]")

0 commit comments

Comments
 (0)