Skip to content

Commit 94f8a2d

Browse files
committed
Handled more options at bytearray init
1 parent a53757c commit 94f8a2d

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

grumpy-runtime-src/runtime/bytearray.go

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,52 @@ func byteArrayGT(f *Frame, v, w *Object) (*Object, *BaseException) {
9898
}
9999

100100
func byteArrayInit(f *Frame, o *Object, args Args, _ KWArgs) (*Object, *BaseException) {
101-
if raised := checkFunctionArgs(f, "__init__", args, IntType); raised != nil {
101+
argc := len(args)
102+
if argc == 0 {
103+
return None, nil
104+
}
105+
expectedTypes := []*Type{ObjectType}
106+
if raised := checkFunctionArgs(f, "__init__", args, expectedTypes...); raised != nil {
102107
return nil, raised
103108
}
104109
a := toByteArrayUnsafe(o)
110+
if args[0].isInstance(IntType) {
111+
a.mutex.Lock()
112+
a.value = make([]byte, toIntUnsafe(args[0]).Value())
113+
a.mutex.Unlock()
114+
return None, nil
115+
}
116+
// else it must be an iterable
117+
value := []byte{}
118+
iter, raised := Iter(f, args[0])
119+
if raised != nil {
120+
return nil, raised
121+
}
122+
item, raised := Next(f, iter)
123+
for ; raised == nil; item, raised = Next(f, iter) {
124+
switch {
125+
case item.isInstance(StrType):
126+
sval := toStrUnsafe(item).Value()
127+
if len(sval) != 1 {
128+
return nil, f.RaiseType(ValueErrorType, "string must be of size 1")
129+
}
130+
value = append(value, sval[0])
131+
case item.isInstance(IntType):
132+
ival := toIntUnsafe(item).Value()
133+
if ival < 0 || ival >= 256 {
134+
return nil, f.RaiseType(ValueErrorType, "byte must be in range(0, 256)")
135+
}
136+
value = append(value, byte(ival))
137+
default:
138+
return nil, f.RaiseType(TypeErrorType, "an integer or string of size 1 is required")
139+
}
140+
}
141+
if !raised.isInstance(StopIterationType) {
142+
return nil, raised
143+
}
144+
f.RestoreExc(nil, nil)
105145
a.mutex.Lock()
106-
a.value = make([]byte, toIntUnsafe(args[0]).Value())
146+
a.value = value
107147
a.mutex.Unlock()
108148
return None, nil
109149
}

grumpy-runtime-src/runtime/bytearray_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,18 @@ func TestByteArrayGetItem(t *testing.T) {
6868

6969
func TestByteArrayInit(t *testing.T) {
7070
cases := []invokeTestCase{
71+
{args: wrapArgs(), want: newTestByteArray("").ToObject()},
7172
{args: wrapArgs(3), want: newTestByteArray("\x00\x00\x00").ToObject()},
72-
{args: wrapArgs(newObject(ObjectType)), wantExc: mustCreateException(TypeErrorType, `'__init__' requires a 'int' object but received a "object"`)},
73+
{args: wrapArgs([]int{3, 2, 1}), want: newTestByteArray("\x03\x02\x01").ToObject()},
74+
{args: wrapArgs("abc"), want: newTestByteArray("abc").ToObject()},
75+
{args: wrapArgs([]string{"a", "b", "c"}), want: newTestByteArray("abc").ToObject()},
76+
{args: wrapArgs(newTestXRange(3)), want: newTestByteArray("\x00\x01\x02").ToObject()},
77+
{args: wrapArgs(newTestRange(3)), want: newTestByteArray("\x00\x01\x02").ToObject()},
78+
{args: wrapArgs(newObject(ObjectType)), wantExc: mustCreateException(TypeErrorType, `'object' object is not iterable`)},
79+
{args: wrapArgs([]int{-1}), wantExc: mustCreateException(ValueErrorType, `byte must be in range(0, 256)`)},
80+
{args: wrapArgs([]int{256}), wantExc: mustCreateException(ValueErrorType, `byte must be in range(0, 256)`)},
81+
{args: wrapArgs([]string{"ab"}), wantExc: mustCreateException(ValueErrorType, `string must be of size 1`)},
82+
{args: wrapArgs([]interface{}{5, []interface{}{}}), wantExc: mustCreateException(TypeErrorType, `an integer or string of size 1 is required`)},
7383
}
7484
for _, cas := range cases {
7585
if err := runInvokeTestCase(ByteArrayType.ToObject(), &cas); err != "" {

0 commit comments

Comments
 (0)