Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 69 additions & 17 deletions stdlib/array/array.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import (
"github.com/go-python/gpython/py"
)

// FIXME(sbinet): consider creating an "array handler" type for each of the typecodes
// and make the handler a field of the "array" type.
// or make "array" an interface ?

// array provides efficient manipulation of C-arrays (as Go slices).
type array struct {
descr byte // typecode of elements
esize int // element size in bytes
Expand Down Expand Up @@ -197,12 +202,12 @@ func array_new(metatype *py.Type, args py.Tuple, kwargs py.StringDict) (py.Objec
esize: descr2esize[descr[0]],
}

if descr[0] == 'u' {
// FIXME(sbinet)
return nil, py.NotImplementedError
}

switch descr[0] {
case 'u':
var data []rune
arr.data = data
arr.append = arr.appendRune
arr.extend = arr.extendRune
case 'b':
var data []int8
arr.data = data
Expand Down Expand Up @@ -300,14 +305,22 @@ func (arr *array) M__repr__() (py.Object, error) {
o := new(strings.Builder)
o.WriteString("array('" + string(arr.descr) + "'")
if data := reflect.ValueOf(arr.data); arr.data != nil && data.Len() > 0 {
o.WriteString(", [")
for i := 0; i < data.Len(); i++ {
if i > 0 {
o.WriteString(", ")
switch arr.descr {
case 'u':
o.WriteString(", '")
o.WriteString(string(arr.data.([]rune)))
o.WriteString("'")
default:
o.WriteString(", [")
for i := 0; i < data.Len(); i++ {
if i > 0 {
o.WriteString(", ")
}
// FIXME(sbinet): we don't get exactly the same display wrt CPython for float32
fmt.Fprintf(o, "%v", data.Index(i))
}
fmt.Fprintf(o, "%v", data.Index(i))
o.WriteString("]")
}
o.WriteString("]")
}
o.WriteString(")")
return py.String(o.String()), nil
Expand Down Expand Up @@ -344,8 +357,7 @@ func (arr *array) M__getitem__(k py.Object) (py.Object, error) {
case 'B', 'H', 'I', 'L', 'Q':
return py.Int(sli.Index(i).Uint()), nil
case 'u':
// FIXME(sbinet)
return nil, py.NotImplementedError
return py.String([]rune{rune(sli.Index(i).Int())}), nil
case 'f', 'd':
return py.Float(sli.Index(i).Float()), nil
}
Expand All @@ -372,14 +384,23 @@ func (arr *array) M__setitem__(k, v py.Object) (py.Object, error) {
}
switch arr.descr {
case 'b', 'h', 'i', 'l', 'q':
vv := v.(py.Int)
vv, ok := v.(py.Int)
if !ok {
return nil, py.ExceptionNewf(py.TypeError, "'%s' object cannot be interpreted as an integer", v.Type().Name)
}
sli.Index(i).SetInt(int64(vv))
case 'B', 'H', 'I', 'L', 'Q':
vv := v.(py.Int)
vv, ok := v.(py.Int)
if !ok {
return nil, py.ExceptionNewf(py.TypeError, "'%s' object cannot be interpreted as an integer", v.Type().Name)
}
sli.Index(i).SetUint(uint64(vv))
case 'u':
// FIXME(sbinet)
return nil, py.NotImplementedError
vv, ok := v.(py.Int)
if !ok {
return nil, py.ExceptionNewf(py.TypeError, "array item must be unicode character")
}
sli.Index(i).SetInt(int64(vv))
case 'f', 'd':
var vv float64
switch v := v.(type) {
Expand All @@ -401,6 +422,16 @@ func (arr *array) M__setitem__(k, v py.Object) (py.Object, error) {
panic("impossible")
}

func (arr *array) appendRune(v py.Object) (py.Object, error) {
str, ok := v.(py.String)
if !ok {
return nil, py.ExceptionNewf(py.TypeError, "array item must be unicode character")
}

arr.data = append(arr.data.([]rune), []rune(str)...)
return py.None, nil
}

func (arr *array) appendI8(v py.Object) (py.Object, error) {
vv, err := asInt(v)
if err != nil {
Expand Down Expand Up @@ -491,6 +522,27 @@ func (arr *array) appendF64(v py.Object) (py.Object, error) {
return py.None, nil
}

func (arr *array) extendRune(arg py.Object) (py.Object, error) {
itr, err := py.Iter(arg)
if err != nil {
return nil, err
}

nxt := itr.(py.I__next__)

for {
o, err := nxt.M__next__()
if err == py.StopIteration {
break
}
_, err = arr.appendRune(o)
if err != nil {
return nil, err
}
}
return py.None, nil
}

func (arr *array) extendI8(arg py.Object) (py.Object, error) {
itr, err := py.Iter(arg)
if err != nil {
Expand Down
71 changes: 41 additions & 30 deletions stdlib/array/testdata/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,87 +19,105 @@ def assertEqual(x, y):
print("")
print("typecode '%s'" % (typ,))
if typ == 'u':
# FIXME(sbinet): implement
print(" SKIP: NotImplemented")
continue
if typ in "bhilqfd":
arr = array.array(typ, "?世界!")
if typ in "bhilq":
arr = array.array(typ, [-1, -2, -3, -4])
if typ in "BHILQ":
arr = array.array(typ, [+1, +2, +3, +4])
print(" array: %s" % (repr(arr),))
if typ in "fd":
arr = array.array(typ, [-1.0, -2.0, -3.0, -4.0])
print(" array: %s ## repr" % (repr(arr),))
print(" array: %s ## str" % (str(arr),))
print(" itemsize: %s" % (arr.itemsize,))
print(" typecode: %s" % (arr.typecode,))
print(" len: %s" % (len(arr),))
print(" arr[0]: %s" % (arr[0],))
print(" arr[-1]: %s" % (arr[-1],))
try:
arr[-10]
print(" ERROR: expected an exception")
print(" ERROR1: expected an exception")
except:
print(" caught an exception [ok]")

try:
arr[10]
print(" ERROR: expected an exception")
print(" ERROR2: expected an exception")
except:
print(" caught an exception [ok]")
arr[-2] = 33
if typ in "fd":
arr[-2] = 0.3
print(" arr[-2]: %s" % (arr[-2],))

try:
arr[-10] = 2
print(" ERROR: expected an exception")
print(" ERROR3: expected an exception")
except:
print(" caught an exception [ok]")

if typ in "bhilqfd":
arr.extend([-5,-6])
if typ in "BHILQ":
arr.extend([5,6])
if typ == 'u':
arr.extend("he")
print(" array: %s" % (repr(arr),))
print(" len: %s" % (len(arr),))

if typ in "bhilqfd":
arr.append(-7)
if typ in "BHILQ":
arr.append(7)
if typ == 'u':
arr.append("l")
print(" array: %s" % (repr(arr),))
print(" len: %s" % (len(arr),))

try:
arr.append()
print(" ERROR: expected an exception")
print(" ERROR4: expected an exception")
except:
print(" caught an exception [ok]")
try:
arr.append([])
print(" ERROR: expected an exception")
print(" ERROR5: expected an exception")
except:
print(" caught an exception [ok]")
try:
arr.append(1, 2)
print(" ERROR: expected an exception")
print(" ERROR6: expected an exception")
except:
print(" caught an exception [ok]")
try:
arr.append(None)
print(" ERROR: expected an exception")
print(" ERROR7: expected an exception")
except:
print(" caught an exception [ok]")

try:
arr.extend()
print(" ERROR: expected an exception")
print(" ERROR8: expected an exception")
except:
print(" caught an exception [ok]")
try:
arr.extend(None)
print(" ERROR: expected an exception")
print(" ERROR9: expected an exception")
except:
print(" caught an exception [ok]")
try:
arr.extend([1,None])
print(" ERROR: expected an exception")
print(" ERROR10: expected an exception")
except:
print(" caught an exception [ok]")
try:
arr.extend(1,None)
print(" ERROR11: expected an exception")
except:
print(" caught an exception [ok]")

try:
arr[0] = object()
print(" ERROR12: expected an exception")
except:
print(" caught an exception [ok]")
pass
Expand All @@ -108,55 +126,48 @@ def assertEqual(x, y):
print("## testing array.array(...)")
try:
arr = array.array()
print("ERROR: expected an exception")
print("ERROR1: expected an exception")
except:
print("caught an exception [ok]")

try:
arr = array.array(b"d")
print("ERROR: expected an exception")
print("ERROR2: expected an exception")
except:
print("caught an exception [ok]")

try:
arr = array.array("?")
print("ERROR: expected an exception")
print("ERROR3: expected an exception")
except:
print("caught an exception [ok]")

try:
arr = array.array("dd")
print("ERROR: expected an exception")
print("ERROR4: expected an exception")
except:
print("caught an exception [ok]")

try:
arr = array.array("d", initializer=[1,2])
print("ERROR: expected an exception")
print("ERROR5: expected an exception")
except:
print("caught an exception [ok]")

try:
arr = array.array("d", [1], [])
print("ERROR: expected an exception")
print("ERROR6: expected an exception")
except:
print("caught an exception [ok]")

try:
arr = array.array("d", 1)
print("ERROR: expected an exception")
print("ERROR7: expected an exception")
except:
print("caught an exception [ok]")

try:
arr = array.array("d", ["a","b"])
print("ERROR: expected an exception")
except:
print("caught an exception [ok]")

try:
## FIXME(sbinet): implement it at some point.
arr = array.array("u")
print("ERROR: expected an exception")
print("ERROR8: expected an exception")
except:
print("caught an exception [ok]")
Loading