github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/runtime/core_test.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package grumpy
    16  
    17  import (
    18  	"fmt"
    19  	"math/big"
    20  	"reflect"
    21  	"regexp"
    22  	"runtime"
    23  	"testing"
    24  )
    25  
    26  func TestAssert(t *testing.T) {
    27  	assert := newBuiltinFunction("TestAssert", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
    28  		switch argc := len(args); argc {
    29  		case 1:
    30  			if raised := Assert(f, args[0], nil); raised != nil {
    31  				return nil, raised
    32  			}
    33  		case 2:
    34  			if raised := Assert(f, args[0], args[1]); raised != nil {
    35  				return nil, raised
    36  			}
    37  		default:
    38  			return nil, f.RaiseType(SystemErrorType, fmt.Sprintf("Assert expected 1 or 2 args, got %d", argc))
    39  		}
    40  		return None, nil
    41  	}).ToObject()
    42  	emptyAssert := toBaseExceptionUnsafe(mustNotRaise(AssertionErrorType.Call(NewRootFrame(), nil, nil)))
    43  	cases := []invokeTestCase{
    44  		{args: wrapArgs(true), want: None},
    45  		{args: wrapArgs(NewTuple(None)), want: None},
    46  		{args: wrapArgs(None), wantExc: emptyAssert},
    47  		{args: wrapArgs(NewDict()), wantExc: emptyAssert},
    48  		{args: wrapArgs(false, "foo"), wantExc: mustCreateException(AssertionErrorType, "foo")},
    49  	}
    50  	for _, cas := range cases {
    51  		if err := runInvokeTestCase(assert, &cas); err != "" {
    52  			t.Error(err)
    53  		}
    54  	}
    55  }
    56  
    57  func TestBinaryOps(t *testing.T) {
    58  	fooType := newTestClass("Foo", []*Type{ObjectType}, newStringDict(map[string]*Object{
    59  		"__add__": newBuiltinFunction("__add__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    60  			return NewStr("foo add").ToObject(), nil
    61  		}).ToObject(),
    62  		"__radd__": newBuiltinFunction("__add__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    63  			return NewStr("foo radd").ToObject(), nil
    64  		}).ToObject(),
    65  	}))
    66  	barType := newTestClass("Bar", []*Type{fooType}, NewDict())
    67  	bazType := newTestClass("Baz", []*Type{IntType}, newStringDict(map[string]*Object{
    68  		"__rdiv__": newBuiltinFunction("__rdiv__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    69  			s, raised := ToStr(f, args[1])
    70  			if raised != nil {
    71  				return nil, raised
    72  			}
    73  			return s.ToObject(), nil
    74  		}).ToObject(),
    75  	}))
    76  	inplaceType := newTestClass("Inplace", []*Type{ObjectType}, newStringDict(map[string]*Object{
    77  		"__iadd__": newBuiltinFunction("__iadd__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    78  			return args[1], nil
    79  		}).ToObject(),
    80  		"__iand__": newBuiltinFunction("__iand__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    81  			return args[1], nil
    82  		}).ToObject(),
    83  		"__idiv__": newBuiltinFunction("__idiv__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    84  			return args[1], nil
    85  		}).ToObject(),
    86  		"__ilshift__": newBuiltinFunction("__ilshift__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    87  			return args[1], nil
    88  		}).ToObject(),
    89  		"__imod__": newBuiltinFunction("__imod__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    90  			return args[1], nil
    91  		}).ToObject(),
    92  		"__imul__": newBuiltinFunction("__imul__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    93  			return args[1], nil
    94  		}).ToObject(),
    95  		"__ior__": newBuiltinFunction("__ior__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    96  			return args[1], nil
    97  		}).ToObject(),
    98  		"__irshift__": newBuiltinFunction("__irshift__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    99  			return args[1], nil
   100  		}).ToObject(),
   101  		"__isub__": newBuiltinFunction("__isub__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   102  			return args[1], nil
   103  		}).ToObject(),
   104  		"__ixor__": newBuiltinFunction("__ixor__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   105  			return args[1], nil
   106  		}).ToObject(),
   107  	}))
   108  	cases := []struct {
   109  		fun     func(f *Frame, v, w *Object) (*Object, *BaseException)
   110  		v, w    *Object
   111  		want    *Object
   112  		wantExc *BaseException
   113  	}{
   114  		{Add, NewStr("foo").ToObject(), NewStr("bar").ToObject(), NewStr("foobar").ToObject(), nil},
   115  		{Add, NewStr("foo").ToObject(), NewStr("bar").ToObject(), NewStr("foobar").ToObject(), nil},
   116  		{Add, newObject(fooType), newObject(ObjectType), NewStr("foo add").ToObject(), nil},
   117  		{And, NewInt(-42).ToObject(), NewInt(244).ToObject(), NewInt(212).ToObject(), nil},
   118  		{And, NewInt(42).ToObject(), NewStr("foo").ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for &: 'int' and 'str'")},
   119  		{Add, newObject(fooType), newObject(barType), NewStr("foo add").ToObject(), nil},
   120  		{Div, NewInt(123).ToObject(), newObject(bazType), NewStr("123").ToObject(), nil},
   121  		{IAdd, NewStr("foo").ToObject(), NewStr("bar").ToObject(), NewStr("foobar").ToObject(), nil},
   122  		{IAdd, NewStr("foo").ToObject(), NewStr("bar").ToObject(), NewStr("foobar").ToObject(), nil},
   123  		{IAdd, newObject(fooType), newObject(ObjectType), NewStr("foo add").ToObject(), nil},
   124  		{IAdd, newObject(inplaceType), NewStr("foo").ToObject(), NewStr("foo").ToObject(), nil},
   125  		{IAnd, NewInt(9).ToObject(), NewInt(12).ToObject(), NewInt(8).ToObject(), nil},
   126  		{IAnd, newObject(inplaceType), NewStr("foo").ToObject(), NewStr("foo").ToObject(), nil},
   127  		{IAnd, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for &: 'object' and 'Foo'")},
   128  		{IDiv, NewInt(123).ToObject(), newObject(bazType), NewStr("123").ToObject(), nil},
   129  		{IDiv, newObject(inplaceType), NewInt(42).ToObject(), NewInt(42).ToObject(), nil},
   130  		{ILShift, newObject(inplaceType), NewInt(123).ToObject(), NewInt(123).ToObject(), nil},
   131  		{IMod, NewInt(24).ToObject(), NewInt(6).ToObject(), NewInt(0).ToObject(), nil},
   132  		{IMod, newObject(inplaceType), NewFloat(3.14).ToObject(), NewFloat(3.14).ToObject(), nil},
   133  		{IMul, NewStr("foo").ToObject(), NewInt(3).ToObject(), NewStr("foofoofoo").ToObject(), nil},
   134  		{IMul, newObject(inplaceType), True.ToObject(), True.ToObject(), nil},
   135  		{IMul, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for *: 'object' and 'Foo'")},
   136  		{IOr, newObject(inplaceType), NewInt(42).ToObject(), NewInt(42).ToObject(), nil},
   137  		{IOr, NewInt(9).ToObject(), NewInt(12).ToObject(), NewInt(13).ToObject(), nil},
   138  		{IOr, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for |: 'object' and 'Foo'")},
   139  		{IRShift, newObject(inplaceType), NewInt(123).ToObject(), NewInt(123).ToObject(), nil},
   140  		{ISub, NewInt(3).ToObject(), NewInt(-3).ToObject(), NewInt(6).ToObject(), nil},
   141  		{ISub, newObject(inplaceType), None, None, nil},
   142  		{IXor, newObject(inplaceType), None, None, nil},
   143  		{IXor, NewInt(9).ToObject(), NewInt(12).ToObject(), NewInt(5).ToObject(), nil},
   144  		{IXor, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for ^: 'object' and 'Foo'")},
   145  		{Mod, NewInt(24).ToObject(), NewInt(6).ToObject(), NewInt(0).ToObject(), nil},
   146  		{Mul, NewStr("foo").ToObject(), NewInt(3).ToObject(), NewStr("foofoofoo").ToObject(), nil},
   147  		{Mul, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for *: 'object' and 'Foo'")},
   148  		{Or, NewInt(-42).ToObject(), NewInt(244).ToObject(), NewInt(-10).ToObject(), nil},
   149  		{Or, NewInt(42).ToObject(), NewStr("foo").ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for |: 'int' and 'str'")},
   150  		{Pow, NewInt(2).ToObject(), NewInt(-2).ToObject(), NewFloat(0.25).ToObject(), nil},
   151  		{Pow, NewInt(2).ToObject(), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for **: 'int' and 'Foo'")},
   152  		{Sub, NewInt(3).ToObject(), NewInt(-3).ToObject(), NewInt(6).ToObject(), nil},
   153  		{Xor, NewInt(-42).ToObject(), NewInt(244).ToObject(), NewInt(-222).ToObject(), nil},
   154  		{Xor, NewInt(42).ToObject(), NewStr("foo").ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for ^: 'int' and 'str'")},
   155  	}
   156  	for _, cas := range cases {
   157  		testCase := invokeTestCase{wrapArgs(cas.v, cas.w), nil, cas.want, cas.wantExc}
   158  		if err := runInvokeTestCase(wrapFuncForTest(cas.fun), &testCase); err != "" {
   159  			t.Error(err)
   160  		}
   161  	}
   162  }
   163  
   164  func TestCompare(t *testing.T) {
   165  	badCmpType := newTestClass("BadCmp", []*Type{ObjectType}, newStringDict(map[string]*Object{
   166  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   167  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   168  		}).ToObject(),
   169  	}))
   170  	cmpLtType := newTestClass("Lt", []*Type{ObjectType}, newStringDict(map[string]*Object{
   171  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   172  			return NewInt(-1).ToObject(), nil
   173  		}).ToObject(),
   174  	}))
   175  	cmpEqType := newTestClass("Eq", []*Type{ObjectType}, newStringDict(map[string]*Object{
   176  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   177  			return NewInt(0).ToObject(), nil
   178  		}).ToObject(),
   179  	}))
   180  	cmpGtType := newTestClass("Gt", []*Type{ObjectType}, newStringDict(map[string]*Object{
   181  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   182  			return NewInt(1).ToObject(), nil
   183  		}).ToObject(),
   184  	}))
   185  	cmpByEqType := newTestClass("EqCmp", []*Type{IntType}, newStringDict(map[string]*Object{
   186  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   187  			return True.ToObject(), nil
   188  		}).ToObject(),
   189  	}))
   190  	badCmpByEqType := newTestClass("BadEqCmp", []*Type{IntType}, newStringDict(map[string]*Object{
   191  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   192  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   193  		}).ToObject(),
   194  	}))
   195  	badNonZeroType := newTestClass("BadNonZeroType", []*Type{ObjectType}, newStringDict(map[string]*Object{
   196  		"__nonzero__": newBuiltinFunction("__nonzero__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   197  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   198  		}).ToObject(),
   199  	}))
   200  	worseCmpByEqType := newTestClass("WorseEqCmp", []*Type{IntType}, newStringDict(map[string]*Object{
   201  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   202  			return newObject(badNonZeroType), nil
   203  		}).ToObject(),
   204  	}))
   205  	cmpNonIntResultType := newTestClass("CmpNonIntResult", []*Type{ObjectType}, newStringDict(map[string]*Object{
   206  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   207  			return NewStr("foo").ToObject(), nil
   208  		}).ToObject(),
   209  	}))
   210  	cases := []invokeTestCase{
   211  		// Test `__cmp__` less than.
   212  		{args: wrapArgs(newObject(cmpLtType), None), want: NewInt(-1).ToObject()},
   213  		{args: wrapArgs(None, newObject(cmpGtType)), want: NewInt(-1).ToObject()},
   214  		// Test `__cmp__` equals.
   215  		{args: wrapArgs(newObject(cmpEqType), None), want: NewInt(0).ToObject()},
   216  		{args: wrapArgs(None, newObject(cmpEqType)), want: NewInt(0).ToObject()},
   217  		// Test `__cmp__` greater than.
   218  		{args: wrapArgs(newObject(cmpGtType), None), want: NewInt(1).ToObject()},
   219  		{args: wrapArgs(None, newObject(cmpLtType)), want: NewInt(1).ToObject()},
   220  		// Test `__cmp__` fallback to rich comparison.
   221  		{args: wrapArgs(newObject(cmpByEqType), None), want: NewInt(0).ToObject()},
   222  		{args: wrapArgs(None, newObject(cmpByEqType)), want: NewInt(0).ToObject()},
   223  		// Test bad `__cmp__` fallback to rich comparison.
   224  		{args: wrapArgs(newObject(badCmpByEqType), None), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   225  		{args: wrapArgs(None, newObject(badCmpByEqType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   226  		// Test bad `__cmp__` fallback to rich comparison where a bad object is returned from `__eq__`.
   227  		{args: wrapArgs(newObject(worseCmpByEqType), None), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   228  		{args: wrapArgs(None, newObject(worseCmpByEqType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   229  		// Test bad `__cmp__`.
   230  		{args: wrapArgs(newObject(badCmpType), None), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   231  		{args: wrapArgs(None, newObject(badCmpType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   232  		// Test bad `__cmp__` with non-int result.
   233  		{args: wrapArgs(newObject(cmpNonIntResultType), None), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   234  		{args: wrapArgs(None, newObject(cmpNonIntResultType)), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   235  	}
   236  	for _, cas := range cases {
   237  		if err := runInvokeTestCase(wrapFuncForTest(Compare), &cas); err != "" {
   238  			t.Error(err)
   239  		}
   240  	}
   241  }
   242  
   243  func TestCompareDefault(t *testing.T) {
   244  	o1, o2 := newObject(ObjectType), newObject(ObjectType)
   245  	// Make sure uintptr(o1) < uintptr(o2).
   246  	if uintptr(o1.toPointer()) > uintptr(o2.toPointer()) {
   247  		o1, o2 = o2, o1
   248  	}
   249  	// When type names are equal, comparison should fall back to comparing
   250  	// the pointer values of the types of the objects.
   251  	fakeObjectType := newTestClass("object", []*Type{ObjectType}, NewDict())
   252  	o3, o4 := newObject(fakeObjectType), newObject(ObjectType)
   253  	if uintptr(o3.typ.toPointer()) > uintptr(o4.typ.toPointer()) {
   254  		o3, o4 = o4, o3
   255  	}
   256  	// An int subtype that equals anything, but doesn't override other
   257  	// comparison methods.
   258  	eqType := newTestClass("Eq", []*Type{IntType}, newStringDict(map[string]*Object{
   259  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   260  			return True.ToObject(), nil
   261  		}).ToObject(),
   262  		"__repr__": newBuiltinFunction("__repr__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   263  			return NewStr("<Foo>").ToObject(), nil
   264  		}).ToObject(),
   265  	}))
   266  	cases := []invokeTestCase{
   267  		{args: wrapArgs(true, o1), want: compareAllResultLT},
   268  		{args: wrapArgs(o1, -306), want: compareAllResultGT},
   269  		{args: wrapArgs(-306, o1), want: compareAllResultLT},
   270  		{args: wrapArgs(NewList(), None), want: compareAllResultGT},
   271  		{args: wrapArgs(None, "foo"), want: compareAllResultLT},
   272  		{args: wrapArgs(o1, o1), want: compareAllResultEq},
   273  		{args: wrapArgs(o1, o2), want: compareAllResultLT},
   274  		{args: wrapArgs(o2, o1), want: compareAllResultGT},
   275  		{args: wrapArgs(o3, o4), want: compareAllResultLT},
   276  		{args: wrapArgs(o4, o3), want: compareAllResultGT},
   277  		// The equality test should dispatch to the eqType instance and
   278  		// return true.
   279  		{args: wrapArgs(42, newObject(eqType)), want: newTestTuple(false, false, true, true, true, true).ToObject()},
   280  	}
   281  	for _, cas := range cases {
   282  		if err := runInvokeTestCase(compareAll, &cas); err != "" {
   283  			t.Error(err)
   284  		}
   285  	}
   286  }
   287  
   288  func TestContains(t *testing.T) {
   289  	cases := []invokeTestCase{
   290  		{args: wrapArgs(NewTuple(), 42), want: False.ToObject()},
   291  		{args: wrapArgs(newTestList("foo", "bar"), "bar"), want: True.ToObject()},
   292  		{args: wrapArgs(newTestDict(1, "foo", 2, "bar", 3, "baz"), 2), want: True.ToObject()},
   293  		{args: wrapArgs("foobar", "ooba"), want: True.ToObject()},
   294  		{args: wrapArgs("qux", "ooba"), want: False.ToObject()},
   295  		{args: wrapArgs(3.14, None), wantExc: mustCreateException(TypeErrorType, "'float' object is not iterable")},
   296  	}
   297  	for _, cas := range cases {
   298  		if err := runInvokeTestCase(wrapFuncForTest(Contains), &cas); err != "" {
   299  			t.Error(err)
   300  		}
   301  	}
   302  }
   303  
   304  // DelAttr is tested in TestObjectDelAttr.
   305  
   306  func TestDelItem(t *testing.T) {
   307  	delItem := newBuiltinFunction("TestDelItem", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   308  		if raised := checkFunctionArgs(f, "TestDelItem", args, ObjectType, ObjectType); raised != nil {
   309  			return nil, raised
   310  		}
   311  		o := args[0]
   312  		if raised := DelItem(f, o, args[1]); raised != nil {
   313  			return nil, raised
   314  		}
   315  		return args[0], nil
   316  	}).ToObject()
   317  	cases := []invokeTestCase{
   318  		{args: wrapArgs(newTestDict("foo", None), "foo"), want: NewDict().ToObject()},
   319  		{args: wrapArgs(NewDict(), "foo"), wantExc: mustCreateException(KeyErrorType, "foo")},
   320  		{args: wrapArgs(123, "bar"), wantExc: mustCreateException(TypeErrorType, "'int' object does not support item deletion")},
   321  	}
   322  	for _, cas := range cases {
   323  		if err := runInvokeTestCase(delItem, &cas); err != "" {
   324  			t.Error(err)
   325  		}
   326  	}
   327  }
   328  
   329  func TestFormatException(t *testing.T) {
   330  	fun := wrapFuncForTest(func(f *Frame, t *Type, args ...*Object) (string, *BaseException) {
   331  		e, raised := t.Call(f, args, nil)
   332  		if raised != nil {
   333  			return "", raised
   334  		}
   335  		f.Raise(e, nil, nil)
   336  		s := FormatExc(f)
   337  		f.RestoreExc(nil, nil)
   338  		return s, nil
   339  	})
   340  	cases := []invokeTestCase{
   341  		{args: wrapArgs(ExceptionType), want: NewStr("Exception\n").ToObject()},
   342  		{args: wrapArgs(AttributeErrorType, ""), want: NewStr("AttributeError\n").ToObject()},
   343  		{args: wrapArgs(TypeErrorType, 123), want: NewStr("TypeError: 123\n").ToObject()},
   344  		{args: wrapArgs(AttributeErrorType, "hello", "there"), want: NewStr("AttributeError: ('hello', 'there')\n").ToObject()},
   345  	}
   346  	for _, cas := range cases {
   347  		if err := runInvokeTestCase(fun, &cas); err != "" {
   348  			t.Error(err)
   349  		}
   350  	}
   351  }
   352  
   353  func TestGetAttr(t *testing.T) {
   354  	getAttr := newBuiltinFunction("TestGetAttr", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   355  		expectedTypes := []*Type{ObjectType, StrType, ObjectType}
   356  		argc := len(args)
   357  		if argc == 2 {
   358  			expectedTypes = expectedTypes[:2]
   359  		}
   360  		if raised := checkFunctionArgs(f, "TestGetAttr", args, expectedTypes...); raised != nil {
   361  			return nil, raised
   362  		}
   363  		var def *Object
   364  		if argc > 2 {
   365  			def = args[2]
   366  		}
   367  		s, raised := ToStr(f, args[1])
   368  		if raised != nil {
   369  			return nil, raised
   370  		}
   371  		return GetAttr(f, args[0], s, def)
   372  	}).ToObject()
   373  	fooResult := newObject(ObjectType)
   374  	fooType := newTestClass("Foo", []*Type{ObjectType}, newStringDict(map[string]*Object{
   375  		"__getattribute__": newBuiltinFunction("__getattribute__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   376  			return fooResult, nil
   377  		}).ToObject(),
   378  	}))
   379  	barType := newTestClass("Bar", []*Type{ObjectType}, newStringDict(map[string]*Object{
   380  		"__getattribute__": newBuiltinFunction("__getattribute__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   381  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   382  		}).ToObject(),
   383  	}))
   384  	cases := []invokeTestCase{
   385  		{args: wrapArgs(newObject(fooType), "bar"), want: fooResult},
   386  		{args: wrapArgs(newObject(fooType), "baz", None), want: fooResult},
   387  		{args: wrapArgs(newObject(ObjectType), "qux", None), want: None},
   388  		{args: wrapArgs(NewTuple(), "noexist"), wantExc: mustCreateException(AttributeErrorType, "'tuple' object has no attribute 'noexist'")},
   389  		{args: wrapArgs(DictType, "noexist"), wantExc: mustCreateException(AttributeErrorType, "type object 'dict' has no attribute 'noexist'")},
   390  		{args: wrapArgs(newObject(barType), "noexist"), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   391  	}
   392  	for _, cas := range cases {
   393  		if err := runInvokeTestCase(getAttr, &cas); err != "" {
   394  			t.Error(err)
   395  		}
   396  	}
   397  }
   398  
   399  func TestGetItem(t *testing.T) {
   400  	cases := []invokeTestCase{
   401  		{args: wrapArgs(newStringDict(map[string]*Object{"foo": None}), "foo"), want: None},
   402  		{args: wrapArgs(NewDict(), "bar"), wantExc: mustCreateException(KeyErrorType, "bar")},
   403  		{args: wrapArgs(true, "baz"), wantExc: mustCreateException(TypeErrorType, "'bool' object has no attribute '__getitem__'")},
   404  	}
   405  	for _, cas := range cases {
   406  		if err := runInvokeTestCase(wrapFuncForTest(GetItem), &cas); err != "" {
   407  			t.Error(err)
   408  		}
   409  	}
   410  }
   411  
   412  func TestHash(t *testing.T) {
   413  	badHash := newTestClass("badHash", []*Type{ObjectType}, newStringDict(map[string]*Object{
   414  		"__hash__": newBuiltinFunction("__hash__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   415  			return args[0], nil
   416  		}).ToObject(),
   417  	}))
   418  	o := newObject(ObjectType)
   419  	cases := []invokeTestCase{
   420  		{args: wrapArgs("foo"), want: hashFoo},
   421  		{args: wrapArgs(123), want: NewInt(123).ToObject()},
   422  		{args: wrapArgs(o), want: NewInt(int(uintptr(o.toPointer()))).ToObject()},
   423  		{args: wrapArgs(NewList()), wantExc: mustCreateException(TypeErrorType, "unhashable type: 'list'")},
   424  		{args: wrapArgs(NewDict()), wantExc: mustCreateException(TypeErrorType, "unhashable type: 'dict'")},
   425  		{args: wrapArgs(newObject(badHash)), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   426  	}
   427  	for _, cas := range cases {
   428  		if err := runInvokeTestCase(wrapFuncForTest(Hash), &cas); err != "" {
   429  			t.Error(err)
   430  		}
   431  	}
   432  }
   433  
   434  func TestHex(t *testing.T) {
   435  	badHex := newTestClass("badHex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   436  		"__hex__": newBuiltinFunction("__hex__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   437  			return NewInt(123).ToObject(), nil
   438  		}).ToObject(),
   439  	}))
   440  	goodHex := newTestClass("goodHex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   441  		"__hex__": newBuiltinFunction("__hex__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   442  			return NewStr("0x123").ToObject(), nil
   443  		}).ToObject(),
   444  	}))
   445  	cases := []invokeTestCase{
   446  		{args: wrapArgs(-123), want: NewStr("-0x7b").ToObject()},
   447  		{args: wrapArgs(123), want: NewStr("0x7b").ToObject()},
   448  		{args: wrapArgs(newObject(goodHex)), want: NewStr("0x123").ToObject()},
   449  		{args: wrapArgs(NewList()), wantExc: mustCreateException(TypeErrorType, "hex() argument can't be converted to hex")},
   450  		{args: wrapArgs(NewDict()), wantExc: mustCreateException(TypeErrorType, "hex() argument can't be converted to hex")},
   451  		{args: wrapArgs(newObject(badHex)), wantExc: mustCreateException(TypeErrorType, "__hex__ returned non-string (type int)")},
   452  	}
   453  	for _, cas := range cases {
   454  		if err := runInvokeTestCase(wrapFuncForTest(Hex), &cas); err != "" {
   455  			t.Error(err)
   456  		}
   457  	}
   458  }
   459  
   460  func TestIndex(t *testing.T) {
   461  	goodType := newTestClass("GoodIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   462  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   463  			return NewInt(123).ToObject(), nil
   464  		}).ToObject(),
   465  	}))
   466  	longType := newTestClass("LongIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   467  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   468  			return NewLong(big.NewInt(123)).ToObject(), nil
   469  		}).ToObject(),
   470  	}))
   471  	raiseType := newTestClass("RaiseIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   472  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   473  			return nil, f.RaiseType(RuntimeErrorType, "uh oh")
   474  		}).ToObject(),
   475  	}))
   476  	badType := newTestClass("BadIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   477  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   478  			return NewFloat(3.14).ToObject(), nil
   479  		}).ToObject(),
   480  	}))
   481  	cases := []invokeTestCase{
   482  		{args: wrapArgs(42), want: NewInt(42).ToObject()},
   483  		{args: wrapArgs(newObject(goodType)), want: NewInt(123).ToObject()},
   484  		{args: wrapArgs(newObject(longType)), want: NewLong(big.NewInt(123)).ToObject()},
   485  		{args: wrapArgs(newObject(raiseType)), wantExc: mustCreateException(RuntimeErrorType, "uh oh")},
   486  		{args: wrapArgs(newObject(badType)), wantExc: mustCreateException(TypeErrorType, "__index__ returned non-(int,long) (type float)")},
   487  		{args: wrapArgs("abc"), want: None},
   488  	}
   489  	for _, cas := range cases {
   490  		if err := runInvokeTestCase(wrapFuncForTest(Index), &cas); err != "" {
   491  			t.Error(err)
   492  		}
   493  	}
   494  	cases = []invokeTestCase{
   495  		{args: wrapArgs(42), want: NewInt(42).ToObject()},
   496  		{args: wrapArgs(newObject(goodType)), want: NewInt(123).ToObject()},
   497  		{args: wrapArgs(newObject(raiseType)), wantExc: mustCreateException(RuntimeErrorType, "uh oh")},
   498  	}
   499  	for _, cas := range cases {
   500  		if err := runInvokeMethodTestCase(cas.args[0].typ, "__index__", &cas); err != "" {
   501  			t.Error(err)
   502  		}
   503  	}
   504  }
   505  
   506  func TestInvert(t *testing.T) {
   507  	cases := []invokeTestCase{
   508  		{args: wrapArgs(42), want: NewInt(-43).ToObject()},
   509  		{args: wrapArgs(0), want: NewInt(-1).ToObject()},
   510  		{args: wrapArgs(-35935), want: NewInt(35934).ToObject()},
   511  		{args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "bad operand type for unary ~: 'str'")},
   512  	}
   513  	for _, cas := range cases {
   514  		if err := runInvokeTestCase(wrapFuncForTest(Invert), &cas); err != "" {
   515  			t.Error(err)
   516  		}
   517  	}
   518  }
   519  
   520  func TestIsInstanceIsSubclass(t *testing.T) {
   521  	fooType := newTestClass("Foo", []*Type{ObjectType}, NewDict())
   522  	barType := newTestClass("Bar", []*Type{fooType, IntType}, NewDict())
   523  	cases := []struct {
   524  		o         *Object
   525  		classinfo *Object
   526  		want      *Object
   527  		wantExc   *BaseException
   528  	}{
   529  		{newObject(ObjectType), ObjectType.ToObject(), True.ToObject(), nil},
   530  		{NewInt(42).ToObject(), StrType.ToObject(), False.ToObject(), nil},
   531  		{None, NewTuple(NoneType.ToObject(), IntType.ToObject()).ToObject(), True.ToObject(), nil},
   532  		{NewStr("foo").ToObject(), NewTuple(NoneType.ToObject(), IntType.ToObject()).ToObject(), False.ToObject(), nil},
   533  		{NewStr("foo").ToObject(), NewTuple(IntType.ToObject(), NoneType.ToObject()).ToObject(), False.ToObject(), nil},
   534  		{None, NewTuple().ToObject(), False.ToObject(), nil},
   535  		{newObject(barType), fooType.ToObject(), True.ToObject(), nil},
   536  		{newObject(barType), IntType.ToObject(), True.ToObject(), nil},
   537  		{newObject(fooType), IntType.ToObject(), False.ToObject(), nil},
   538  		{newObject(ObjectType), None, nil, mustCreateException(TypeErrorType, "classinfo must be a type or tuple of types")},
   539  		{newObject(ObjectType), NewTuple(None).ToObject(), nil, mustCreateException(TypeErrorType, "classinfo must be a type or tuple of types")},
   540  	}
   541  	for _, cas := range cases {
   542  		// IsInstance
   543  		testCase := invokeTestCase{args: wrapArgs(cas.o, cas.classinfo), want: cas.want, wantExc: cas.wantExc}
   544  		if err := runInvokeTestCase(wrapFuncForTest(IsInstance), &testCase); err != "" {
   545  			t.Error(err)
   546  		}
   547  		// IsSubclass
   548  		testCase.args = wrapArgs(cas.o.Type(), cas.classinfo)
   549  		if err := runInvokeTestCase(wrapFuncForTest(IsSubclass), &testCase); err != "" {
   550  			t.Error(err)
   551  		}
   552  	}
   553  	// Test that IsSubclass raises when first arg is not a type.
   554  	testCase := invokeTestCase{args: wrapArgs(None, NoneType), wantExc: mustCreateException(TypeErrorType, "issubclass() arg 1 must be a class")}
   555  	if err := runInvokeTestCase(wrapFuncForTest(IsSubclass), &testCase); err != "" {
   556  		t.Error(err)
   557  	}
   558  }
   559  
   560  func TestIsTrue(t *testing.T) {
   561  	badNonZeroType := newTestClass("BadNonZeroType", []*Type{ObjectType}, newStringDict(map[string]*Object{
   562  		"__nonzero__": newBuiltinFunction("__nonzero__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   563  			return None, nil
   564  		}).ToObject(),
   565  	}))
   566  	badLenType := newTestClass("BadLen", []*Type{ObjectType}, newStringDict(map[string]*Object{
   567  		"__len__": newBuiltinFunction("__len__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   568  			return None, nil
   569  		}).ToObject(),
   570  	}))
   571  	cases := []invokeTestCase{
   572  		// Bool
   573  		{args: wrapArgs(true), want: True.ToObject()},
   574  		{args: wrapArgs(false), want: False.ToObject()},
   575  		// Dict
   576  		{args: wrapArgs(NewDict()), want: False.ToObject()},
   577  		{args: wrapArgs(newStringDict(map[string]*Object{"foo": True.ToObject()})), want: True.ToObject()},
   578  		// Int
   579  		{args: wrapArgs(0), want: False.ToObject()},
   580  		{args: wrapArgs(-1020), want: True.ToObject()},
   581  		{args: wrapArgs(1698391283), want: True.ToObject()},
   582  		// None
   583  		{args: wrapArgs(None), want: False.ToObject()},
   584  		// Object
   585  		{args: wrapArgs(newObject(ObjectType)), want: True.ToObject()},
   586  		// Str
   587  		{args: wrapArgs(""), want: False.ToObject()},
   588  		{args: wrapArgs("\x00"), want: True.ToObject()},
   589  		{args: wrapArgs("foo"), want: True.ToObject()},
   590  		// Tuple
   591  		{args: wrapArgs(NewTuple()), want: False.ToObject()},
   592  		{args: wrapArgs(newTestTuple("foo", None)), want: True.ToObject()},
   593  		// Funky types
   594  		{args: wrapArgs(newObject(badNonZeroType)), wantExc: mustCreateException(TypeErrorType, "__nonzero__ should return bool, returned NoneType")},
   595  		{args: wrapArgs(newObject(badLenType)), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   596  	}
   597  	for _, cas := range cases {
   598  		if err := runInvokeTestCase(wrapFuncForTest(IsTrue), &cas); err != "" {
   599  			t.Error(err)
   600  		}
   601  	}
   602  }
   603  
   604  func TestIter(t *testing.T) {
   605  	fun := newBuiltinFunction("TestIter", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   606  		if argc := len(args); argc != 1 {
   607  			return nil, f.RaiseType(SystemErrorType, fmt.Sprintf("Iter expected 1 arg, got %d", argc))
   608  		}
   609  		i, raised := Iter(f, args[0])
   610  		if raised != nil {
   611  			return nil, raised
   612  		}
   613  		return Next(f, i)
   614  	}).ToObject()
   615  	cases := []invokeTestCase{
   616  		{args: wrapArgs(NewTuple()), wantExc: mustCreateException(StopIterationType, "")},
   617  		{args: wrapArgs(newTestTuple(42, "foo")), want: NewInt(42).ToObject()},
   618  		{args: wrapArgs(newTestList("foo")), want: NewStr("foo").ToObject()},
   619  		{args: wrapArgs("foo"), want: NewStr("f").ToObject()},
   620  		{args: wrapArgs(123), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")},
   621  	}
   622  	for _, cas := range cases {
   623  		if err := runInvokeTestCase(fun, &cas); err != "" {
   624  			t.Error(err)
   625  		}
   626  	}
   627  }
   628  
   629  func TestIterCallable(t *testing.T) {
   630  	fun := newBuiltinFunction("TestIterCallable", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   631  		if argc := len(args); argc != 2 {
   632  			return nil, f.RaiseType(SystemErrorType, fmt.Sprintf("IterCallable expected 2 arg, got %d", argc))
   633  		}
   634  		i, raised := IterCallable(f, args[0], args[1])
   635  		if raised != nil {
   636  			return nil, raised
   637  		}
   638  		return Next(f, i)
   639  	}).ToObject()
   640  	foo := newBuiltinFunction("foo", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   641  		return NewInt(23).ToObject(), nil
   642  	}).ToObject()
   643  	cases := []invokeTestCase{
   644  		{args: wrapArgs(foo, 23), wantExc: mustCreateException(StopIterationType, "")},
   645  		{args: wrapArgs(foo, 1), want: NewInt(23).ToObject()},
   646  		{args: wrapArgs(123, 1), wantExc: mustCreateException(TypeErrorType, "iter(v, w): v must be callable")},
   647  	}
   648  	for _, cas := range cases {
   649  		if err := runInvokeTestCase(fun, &cas); err != "" {
   650  			t.Error(err)
   651  		}
   652  	}
   653  }
   654  
   655  func TestNeg(t *testing.T) {
   656  	cases := []invokeTestCase{
   657  		{args: wrapArgs(42), want: NewInt(-42).ToObject()},
   658  		{args: wrapArgs(1.2), want: NewFloat(-1.2).ToObject()},
   659  		{args: wrapArgs(NewLong(big.NewInt(123))), want: NewLong(big.NewInt(-123)).ToObject()},
   660  		{args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "bad operand type for unary -: 'str'")},
   661  	}
   662  	for _, cas := range cases {
   663  		if err := runInvokeTestCase(wrapFuncForTest(Neg), &cas); err != "" {
   664  			t.Error(err)
   665  		}
   666  	}
   667  }
   668  
   669  func TestNext(t *testing.T) {
   670  	fun := newBuiltinFunction("TestNext", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   671  		if argc := len(args); argc != 1 {
   672  			return nil, f.RaiseType(SystemErrorType, fmt.Sprintf("Next expected 1 arg, got %d", argc))
   673  		}
   674  		iter := args[0]
   675  		var elems []*Object
   676  		elem, raised := Next(f, iter)
   677  		for ; raised == nil; elem, raised = Next(f, iter) {
   678  			elems = append(elems, elem)
   679  		}
   680  		if !raised.isInstance(StopIterationType) {
   681  			return nil, raised
   682  		}
   683  		f.RestoreExc(nil, nil)
   684  		return NewTuple(elems...).ToObject(), nil
   685  	}).ToObject()
   686  	testElems := []*Object{NewInt(42).ToObject(), NewStr("foo").ToObject(), newObject(ObjectType)}
   687  	cases := []invokeTestCase{
   688  		{args: wrapArgs(mustNotRaise(Iter(NewRootFrame(), NewTuple().ToObject()))), want: NewTuple().ToObject()},
   689  		{args: wrapArgs(mustNotRaise(Iter(NewRootFrame(), NewTuple(testElems...).ToObject()))), want: NewTuple(testElems...).ToObject()},
   690  		{args: wrapArgs(mustNotRaise(Iter(NewRootFrame(), NewList(testElems...).ToObject()))), want: NewTuple(testElems...).ToObject()},
   691  		{args: wrapArgs(123), wantExc: mustCreateException(TypeErrorType, "int object is not an iterator")},
   692  	}
   693  	for _, cas := range cases {
   694  		if err := runInvokeTestCase(fun, &cas); err != "" {
   695  			t.Error(err)
   696  		}
   697  	}
   698  }
   699  
   700  func TestLen(t *testing.T) {
   701  	badLenType := newTestClass("BadLen", []*Type{ObjectType}, newStringDict(map[string]*Object{
   702  		"__len__": newBuiltinFunction("__len__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   703  			return None, nil
   704  		}).ToObject(),
   705  	}))
   706  	cases := []invokeTestCase{
   707  		{args: wrapArgs(NewDict()), want: NewInt(0).ToObject()},
   708  		{args: wrapArgs(newStringDict(map[string]*Object{"foo": NewStr("foo value").ToObject(), "bar": NewStr("bar value").ToObject()})), want: NewInt(2).ToObject()},
   709  		{args: wrapArgs(NewTuple()), want: NewInt(0).ToObject()},
   710  		{args: wrapArgs(NewTuple(None, None, None)), want: NewInt(3).ToObject()},
   711  		{args: wrapArgs(10), wantExc: mustCreateException(TypeErrorType, "object of type 'int' has no len()")},
   712  		{args: wrapArgs(newObject(badLenType)), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   713  	}
   714  	for _, cas := range cases {
   715  		if err := runInvokeTestCase(wrapFuncForTest(Len), &cas); err != "" {
   716  			t.Error(err)
   717  		}
   718  	}
   719  }
   720  
   721  func TestLenRaise(t *testing.T) {
   722  	testTypes := []*Type{
   723  		DictType,
   724  		TupleType,
   725  	}
   726  	for _, typ := range testTypes {
   727  		cases := []invokeTestCase{
   728  			{args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, fmt.Sprintf("unbound method __len__() must be called with %s instance as first argument (got nothing instead)", typ.Name()))},
   729  			{args: wrapArgs(newObject(ObjectType)), wantExc: mustCreateException(TypeErrorType, fmt.Sprintf("unbound method __len__() must be called with %s instance as first argument (got object instance instead)", typ.Name()))},
   730  			{args: wrapArgs(newObject(ObjectType), newObject(ObjectType)), wantExc: mustCreateException(TypeErrorType, fmt.Sprintf("unbound method __len__() must be called with %s instance as first argument (got object instance instead)", typ.Name()))},
   731  		}
   732  		for _, cas := range cases {
   733  			if err := runInvokeMethodTestCase(typ, "__len__", &cas); err != "" {
   734  				t.Error(err)
   735  			}
   736  		}
   737  	}
   738  }
   739  
   740  func TestInvokePositionalArgs(t *testing.T) {
   741  	fun := newBuiltinFunction("TestInvokePositionalArgs", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   742  		return NewTuple(args.makeCopy()...).ToObject(), nil
   743  	}).ToObject()
   744  	cases := []struct {
   745  		varargs *Object
   746  		args    Args
   747  		want    *Object
   748  	}{
   749  		{nil, nil, NewTuple().ToObject()},
   750  		{NewTuple(NewInt(2).ToObject()).ToObject(), nil, NewTuple(NewInt(2).ToObject()).ToObject()},
   751  		{nil, []*Object{NewStr("foo").ToObject()}, NewTuple(NewStr("foo").ToObject()).ToObject()},
   752  		{NewTuple(NewFloat(3.14).ToObject()).ToObject(), []*Object{NewStr("foo").ToObject()}, NewTuple(NewStr("foo").ToObject(), NewFloat(3.14).ToObject()).ToObject()},
   753  		{NewList(NewFloat(3.14).ToObject()).ToObject(), []*Object{NewStr("foo").ToObject()}, NewTuple(NewStr("foo").ToObject(), NewFloat(3.14).ToObject()).ToObject()},
   754  	}
   755  	for _, cas := range cases {
   756  		got, raised := Invoke(NewRootFrame(), fun, cas.args, cas.varargs, nil, nil)
   757  		switch checkResult(got, cas.want, raised, nil) {
   758  		case checkInvokeResultExceptionMismatch:
   759  			t.Errorf("PackArgs(%v, %v) raised %v, want nil", cas.args, cas.varargs, raised)
   760  		case checkInvokeResultReturnValueMismatch:
   761  			t.Errorf("PackArgs(%v, %v) = %v, want %v", cas.args, cas.varargs, got, cas.want)
   762  		}
   763  	}
   764  }
   765  
   766  func TestInvokeKeywordArgs(t *testing.T) {
   767  	fun := newBuiltinFunction("TestInvokeKeywordArgs", func(f *Frame, _ Args, kwargs KWArgs) (*Object, *BaseException) {
   768  		got := map[string]*Object{}
   769  		for _, kw := range kwargs {
   770  			got[kw.Name] = kw.Value
   771  		}
   772  		return newStringDict(got).ToObject(), nil
   773  	}).ToObject()
   774  	d := NewDict()
   775  	d.SetItem(NewRootFrame(), NewInt(123).ToObject(), None)
   776  	cases := []struct {
   777  		keywords KWArgs
   778  		kwargs   *Object
   779  		want     *Object
   780  		wantExc  *BaseException
   781  	}{
   782  		{nil, nil, NewDict().ToObject(), nil},
   783  		{wrapKWArgs("foo", 42), nil, newTestDict("foo", 42).ToObject(), nil},
   784  		{nil, newTestDict("foo", None).ToObject(), newTestDict("foo", None).ToObject(), nil},
   785  		{wrapKWArgs("foo", 42), newTestDict("bar", None).ToObject(), newTestDict("foo", 42, "bar", None).ToObject(), nil},
   786  		{nil, NewList().ToObject(), nil, mustCreateException(TypeErrorType, "argument after ** must be a dict, not list")},
   787  		{nil, d.ToObject(), nil, mustCreateException(TypeErrorType, "keywords must be strings")},
   788  	}
   789  	for _, cas := range cases {
   790  		got, raised := Invoke(NewRootFrame(), fun, nil, nil, cas.keywords, cas.kwargs)
   791  		switch checkResult(got, cas.want, raised, cas.wantExc) {
   792  		case checkInvokeResultExceptionMismatch:
   793  			t.Errorf("PackKwargs(%v, %v) raised %v, want %v", cas.keywords, cas.kwargs, raised, cas.wantExc)
   794  		case checkInvokeResultReturnValueMismatch:
   795  			t.Errorf("PackKwargs(%v, %v) = %v, want %v", cas.keywords, cas.kwargs, got, cas.want)
   796  		}
   797  	}
   798  }
   799  
   800  func TestOct(t *testing.T) {
   801  	badOct := newTestClass("badOct", []*Type{ObjectType}, newStringDict(map[string]*Object{
   802  		"__oct__": newBuiltinFunction("__oct__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   803  			return NewInt(123).ToObject(), nil
   804  		}).ToObject(),
   805  	}))
   806  	goodOct := newTestClass("goodOct", []*Type{ObjectType}, newStringDict(map[string]*Object{
   807  		"__oct__": newBuiltinFunction("__oct__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   808  			return NewStr("0123").ToObject(), nil
   809  		}).ToObject(),
   810  	}))
   811  	cases := []invokeTestCase{
   812  		{args: wrapArgs(-123), want: NewStr("-0173").ToObject()},
   813  		{args: wrapArgs(123), want: NewStr("0173").ToObject()},
   814  		{args: wrapArgs(newObject(goodOct)), want: NewStr("0123").ToObject()},
   815  		{args: wrapArgs(NewList()), wantExc: mustCreateException(TypeErrorType, "oct() argument can't be converted to oct")},
   816  		{args: wrapArgs(NewDict()), wantExc: mustCreateException(TypeErrorType, "oct() argument can't be converted to oct")},
   817  		{args: wrapArgs(newObject(badOct)), wantExc: mustCreateException(TypeErrorType, "__oct__ returned non-string (type int)")},
   818  	}
   819  	for _, cas := range cases {
   820  		if err := runInvokeTestCase(wrapFuncForTest(Oct), &cas); err != "" {
   821  			t.Error(err)
   822  		}
   823  	}
   824  }
   825  
   826  func TestPos(t *testing.T) {
   827  	pos := newTestClass("pos", []*Type{ObjectType}, newStringDict(map[string]*Object{
   828  		"__pos__": newBuiltinFunction("__pos__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   829  			return NewInt(-42).ToObject(), nil
   830  		}).ToObject(),
   831  	}))
   832  	cases := []invokeTestCase{
   833  		{args: wrapArgs(42), want: NewInt(42).ToObject()},
   834  		{args: wrapArgs(1.2), want: NewFloat(1.2).ToObject()},
   835  		{args: wrapArgs(NewLong(big.NewInt(123))), want: NewLong(big.NewInt(123)).ToObject()},
   836  		{args: wrapArgs(newObject(pos)), want: NewInt(-42).ToObject()},
   837  		{args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "bad operand type for unary +: 'str'")},
   838  	}
   839  	for _, cas := range cases {
   840  		if err := runInvokeTestCase(wrapFuncForTest(Pos), &cas); err != "" {
   841  			t.Error(err)
   842  		}
   843  	}
   844  }
   845  
   846  func TestPyPrint(t *testing.T) {
   847  	fun := wrapFuncForTest(func(f *Frame, args *Tuple, sep, end string) (string, *BaseException) {
   848  		return captureStdout(f, func() *BaseException {
   849  			return pyPrint(NewRootFrame(), args.elems, sep, end, Stdout)
   850  		})
   851  	})
   852  	cases := []invokeTestCase{
   853  		{args: wrapArgs(NewTuple(), "", "\n"), want: NewStr("\n").ToObject()},
   854  		{args: wrapArgs(NewTuple(), "", ""), want: NewStr("").ToObject()},
   855  		{args: wrapArgs(newTestTuple("abc", 123), " ", "\n"), want: NewStr("abc 123\n").ToObject()},
   856  		{args: wrapArgs(newTestTuple("foo"), "", " "), want: NewStr("foo ").ToObject()},
   857  	}
   858  	for _, cas := range cases {
   859  		if err := runInvokeTestCase(fun, &cas); err != "" {
   860  			t.Error(err)
   861  		}
   862  	}
   863  }
   864  
   865  // TODO(corona10): Re-enable once #282 is addressed.
   866  /*func TestPrint(t *testing.T) {
   867  	fun := wrapFuncForTest(func(f *Frame, args *Tuple, nl bool) (string, *BaseException) {
   868  		return captureStdout(f, func() *BaseException {
   869  			return Print(NewRootFrame(), args.elems, nl)
   870  		})
   871  	})
   872  	cases := []invokeTestCase{
   873  		{args: wrapArgs(NewTuple(), true), want: NewStr("\n").ToObject()},
   874  		{args: wrapArgs(NewTuple(), false), want: NewStr("").ToObject()},
   875  		{args: wrapArgs(newTestTuple("abc", 123), true), want: NewStr("abc 123\n").ToObject()},
   876  		{args: wrapArgs(newTestTuple("foo"), false), want: NewStr("foo ").ToObject()},
   877  	}
   878  	for _, cas := range cases {
   879  		if err := runInvokeTestCase(fun, &cas); err != "" {
   880  			t.Error(err)
   881  		}
   882  	}
   883  }*/
   884  
   885  func TestReprRaise(t *testing.T) {
   886  	testTypes := []*Type{
   887  		BaseExceptionType,
   888  		BoolType,
   889  		DictType,
   890  		IntType,
   891  		FunctionType,
   892  		StrType,
   893  		TupleType,
   894  		TypeType,
   895  	}
   896  	for _, typ := range testTypes {
   897  		cases := []invokeTestCase{
   898  			{args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, fmt.Sprintf("unbound method __repr__() must be called with %s instance as first argument (got nothing instead)", typ.Name()))},
   899  			{args: wrapArgs(newObject(ObjectType)), wantExc: mustCreateException(TypeErrorType, fmt.Sprintf("unbound method __repr__() must be called with %s instance as first argument (got object instance instead)", typ.Name()))},
   900  		}
   901  		for _, cas := range cases {
   902  			if err := runInvokeMethodTestCase(typ, "__repr__", &cas); err != "" {
   903  				t.Error(err)
   904  			}
   905  		}
   906  	}
   907  }
   908  
   909  func TestReprMethodReturnsNonStr(t *testing.T) {
   910  	// Don't use runInvokeTestCase since it takes repr(args) and in this
   911  	// case repr will raise.
   912  	typ := newTestClass("Foo", []*Type{ObjectType}, newStringDict(map[string]*Object{
   913  		"__repr__": newBuiltinFunction("__repr__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   914  			return None, nil
   915  		}).ToObject(),
   916  	}))
   917  	_, raised := Repr(NewRootFrame(), newObject(typ))
   918  	wantExc := mustCreateException(TypeErrorType, "__repr__ returned non-string (type NoneType)")
   919  	if !exceptionsAreEquivalent(raised, wantExc) {
   920  		t.Errorf(`Repr() raised %v, want %v`, raised, wantExc)
   921  	}
   922  }
   923  
   924  func TestResolveClass(t *testing.T) {
   925  	f := NewRootFrame()
   926  	cases := []struct {
   927  		class   *Dict
   928  		local   *Object
   929  		globals *Dict
   930  		name    string
   931  		want    *Object
   932  		wantExc *BaseException
   933  	}{
   934  		{newStringDict(map[string]*Object{"foo": NewStr("bar").ToObject()}), NewStr("baz").ToObject(), NewDict(), "foo", NewStr("bar").ToObject(), nil},
   935  		{newStringDict(map[string]*Object{"str": NewInt(42).ToObject()}), nil, NewDict(), "str", NewInt(42).ToObject(), nil},
   936  		{NewDict(), nil, newStringDict(map[string]*Object{"foo": NewStr("bar").ToObject()}), "foo", NewStr("bar").ToObject(), nil},
   937  		{NewDict(), nil, NewDict(), "str", StrType.ToObject(), nil},
   938  		{NewDict(), nil, NewDict(), "foo", nil, mustCreateException(NameErrorType, "name 'foo' is not defined")},
   939  	}
   940  	for _, cas := range cases {
   941  		f.globals = cas.globals
   942  		got, raised := ResolveClass(f, cas.class, cas.local, NewStr(cas.name))
   943  		switch checkResult(got, cas.want, raised, cas.wantExc) {
   944  		case checkInvokeResultExceptionMismatch:
   945  			t.Errorf("ResolveClass(%v, %q) raised %v, want %v", cas.globals, cas.name, raised, cas.wantExc)
   946  		case checkInvokeResultReturnValueMismatch:
   947  			t.Errorf("ResolveClass(%v, %q) = %v, want %v", cas.globals, cas.name, got, cas.want)
   948  		}
   949  	}
   950  }
   951  
   952  func TestResolveGlobal(t *testing.T) {
   953  	fun := wrapFuncForTest(func(f *Frame, globals *Dict, name *Str) (*Object, *BaseException) {
   954  		f.globals = globals
   955  		return ResolveGlobal(f, name)
   956  	})
   957  	cases := []invokeTestCase{
   958  		{args: wrapArgs(newStringDict(map[string]*Object{"foo": NewStr("bar").ToObject()}), "foo"), want: NewStr("bar").ToObject()},
   959  		{args: wrapArgs(NewDict(), "str"), want: StrType.ToObject()},
   960  		{args: wrapArgs(NewDict(), "foo"), wantExc: mustCreateException(NameErrorType, "name 'foo' is not defined")},
   961  	}
   962  	for _, cas := range cases {
   963  		if err := runInvokeTestCase(fun, &cas); err != "" {
   964  			t.Error(err)
   965  		}
   966  	}
   967  }
   968  
   969  func TestRichCompare(t *testing.T) {
   970  	badCmpType := newTestClass("BadCmp", []*Type{ObjectType}, newStringDict(map[string]*Object{
   971  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   972  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   973  		}).ToObject(),
   974  	}))
   975  	cmpEqType := newTestClass("BadCmp", []*Type{ObjectType}, newStringDict(map[string]*Object{
   976  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   977  			return NewInt(0).ToObject(), nil
   978  		}).ToObject(),
   979  	}))
   980  	cmpByEqType := newTestClass("Eq", []*Type{IntType}, newStringDict(map[string]*Object{
   981  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   982  			return True.ToObject(), nil
   983  		}).ToObject(),
   984  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   985  			return NotImplemented, nil
   986  		}).ToObject(),
   987  	}))
   988  	badCmpEqType := newTestClass("Eq", []*Type{IntType}, newStringDict(map[string]*Object{
   989  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   990  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   991  		}).ToObject(),
   992  	}))
   993  	cases := []invokeTestCase{
   994  		// Test `__eq__` fallback to `__cmp__`.
   995  		{args: wrapArgs(newObject(cmpEqType), newObject(cmpEqType)), want: compareAllResultEq},
   996  		// Test `__cmp__` fallback to `__eq__`.
   997  		{args: wrapArgs(newObject(cmpByEqType), newObject(cmpByEqType)), want: compareAllResultEq},
   998  		// Test rich compare fallback to bad `__cmp__`.
   999  		{args: wrapArgs(newObject(badCmpType), newObject(badCmpType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
  1000  		// Test bad `__eq__` where the second object being compared is a subclass of the first.
  1001  		{args: wrapArgs(NewInt(13).ToObject(), newObject(badCmpEqType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
  1002  	}
  1003  	for _, cas := range cases {
  1004  		if err := runInvokeTestCase(compareAll, &cas); err != "" {
  1005  			t.Error(err)
  1006  		}
  1007  	}
  1008  }
  1009  
  1010  func TestCheckLocal(t *testing.T) {
  1011  	o := newObject(ObjectType)
  1012  	cases := []invokeTestCase{
  1013  		{args: wrapArgs(o, "foo"), want: None},
  1014  		{args: wrapArgs(UnboundLocal, "bar"), wantExc: mustCreateException(UnboundLocalErrorType, "local variable 'bar' referenced before assignment")},
  1015  	}
  1016  	for _, cas := range cases {
  1017  		if err := runInvokeTestCase(wrapFuncForTest(CheckLocal), &cas); err != "" {
  1018  			t.Error(err)
  1019  		}
  1020  	}
  1021  }
  1022  
  1023  func TestSetItem(t *testing.T) {
  1024  	setItem := newBuiltinFunction("TestSetItem", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
  1025  		if raised := checkFunctionArgs(f, "TestSetItem", args, ObjectType, ObjectType, ObjectType); raised != nil {
  1026  			return nil, raised
  1027  		}
  1028  		o := args[0]
  1029  		if raised := SetItem(f, o, args[1], args[2]); raised != nil {
  1030  			return nil, raised
  1031  		}
  1032  		return o, nil
  1033  	}).ToObject()
  1034  	cases := []invokeTestCase{
  1035  		{args: wrapArgs(NewDict(), "bar", None), want: newTestDict("bar", None).ToObject()},
  1036  		{args: wrapArgs(123, "bar", None), wantExc: mustCreateException(TypeErrorType, "'int' object has no attribute '__setitem__'")},
  1037  	}
  1038  	for _, cas := range cases {
  1039  		if err := runInvokeTestCase(setItem, &cas); err != "" {
  1040  			t.Error(err)
  1041  		}
  1042  	}
  1043  }
  1044  
  1045  func TestStartThread(t *testing.T) {
  1046  	c := make(chan bool)
  1047  	callable := newBuiltinFunction("TestStartThread", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
  1048  		close(c)
  1049  		return None, nil
  1050  	}).ToObject()
  1051  	StartThread(callable)
  1052  	// Deadlock indicates the thread didn't start.
  1053  	<-c
  1054  }
  1055  
  1056  func TestStartThreadRaises(t *testing.T) {
  1057  	// Since there's no way to notify that the goroutine has returned we
  1058  	// can't actually test the exception output but we can at least make
  1059  	// sure the callable ran and didn't blow up the rest of the program.
  1060  	c := make(chan bool)
  1061  	callable := newBuiltinFunction("TestStartThreadRaises", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
  1062  		defer close(c)
  1063  		return nil, f.RaiseType(ExceptionType, "foo")
  1064  	}).ToObject()
  1065  	StartThread(callable)
  1066  	<-c
  1067  }
  1068  
  1069  func TestTie(t *testing.T) {
  1070  	targets := make([]*Object, 3)
  1071  	cases := []struct {
  1072  		t       TieTarget
  1073  		o       *Object
  1074  		want    *Object
  1075  		wantExc *BaseException
  1076  	}{
  1077  		{TieTarget{Target: &targets[0]}, NewInt(42).ToObject(), NewTuple(NewInt(42).ToObject()).ToObject(), nil},
  1078  		{TieTarget{Target: &targets[0]}, NewTuple().ToObject(), NewTuple(NewTuple().ToObject()).ToObject(), nil},
  1079  		{
  1080  			TieTarget{
  1081  				Children: []TieTarget{{Target: &targets[0]}, {Target: &targets[1]}},
  1082  			},
  1083  			NewList(NewStr("foo").ToObject(), NewStr("bar").ToObject()).ToObject(),
  1084  			NewTuple(NewStr("foo").ToObject(), NewStr("bar").ToObject()).ToObject(),
  1085  			nil,
  1086  		},
  1087  		{
  1088  			TieTarget{
  1089  				Children: []TieTarget{
  1090  					{Target: &targets[0]},
  1091  					{Children: []TieTarget{{Target: &targets[1]}, {Target: &targets[2]}}},
  1092  				},
  1093  			},
  1094  			NewTuple(NewStr("foo").ToObject(), NewTuple(NewStr("bar").ToObject(), NewStr("baz").ToObject()).ToObject()).ToObject(),
  1095  			NewTuple(NewStr("foo").ToObject(), NewStr("bar").ToObject(), NewStr("baz").ToObject()).ToObject(),
  1096  			nil,
  1097  		},
  1098  		{
  1099  			TieTarget{
  1100  				Children: []TieTarget{
  1101  					{Target: &targets[0]},
  1102  					{Target: &targets[1]},
  1103  				},
  1104  			},
  1105  			NewList(NewStr("foo").ToObject()).ToObject(),
  1106  			nil,
  1107  			mustCreateException(ValueErrorType, "need more than 1 values to unpack"),
  1108  		},
  1109  		{
  1110  			TieTarget{Children: []TieTarget{{Target: &targets[0]}}},
  1111  			NewTuple(NewInt(1).ToObject(), NewInt(2).ToObject()).ToObject(),
  1112  			nil,
  1113  			mustCreateException(ValueErrorType, "too many values to unpack"),
  1114  		},
  1115  	}
  1116  	for _, cas := range cases {
  1117  		for i := range targets {
  1118  			targets[i] = nil
  1119  		}
  1120  		var got *Object
  1121  		raised := Tie(NewRootFrame(), cas.t, cas.o)
  1122  		if raised == nil {
  1123  			var elems []*Object
  1124  			for _, t := range targets {
  1125  				if t == nil {
  1126  					break
  1127  				}
  1128  				elems = append(elems, t)
  1129  			}
  1130  			got = NewTuple(elems...).ToObject()
  1131  		}
  1132  		switch checkResult(got, cas.want, raised, cas.wantExc) {
  1133  		case checkInvokeResultExceptionMismatch:
  1134  			t.Errorf("Tie(%+v, %v) raised %v, want %v", cas.t, cas.o, raised, cas.wantExc)
  1135  		case checkInvokeResultReturnValueMismatch:
  1136  			t.Errorf("Tie(%+v, %v) = %v, want %v", cas.t, cas.o, got, cas.want)
  1137  		}
  1138  	}
  1139  }
  1140  
  1141  func TestToInt(t *testing.T) {
  1142  	fun := wrapFuncForTest(func(f *Frame, o *Object) (*Tuple, *BaseException) {
  1143  		i, raised := ToInt(f, o)
  1144  		if raised != nil {
  1145  			return nil, raised
  1146  		}
  1147  		return newTestTuple(i, i.Type()), nil
  1148  	})
  1149  	cases := []invokeTestCase{
  1150  		{args: wrapArgs(42), want: newTestTuple(42, IntType).ToObject()},
  1151  		{args: wrapArgs(big.NewInt(123)), want: newTestTuple(123, LongType).ToObject()},
  1152  	}
  1153  	for _, cas := range cases {
  1154  		if err := runInvokeTestCase(fun, &cas); err != "" {
  1155  			t.Error(err)
  1156  		}
  1157  	}
  1158  }
  1159  
  1160  func TestToIntValue(t *testing.T) {
  1161  	cases := []invokeTestCase{
  1162  		{args: wrapArgs(42), want: NewInt(42).ToObject()},
  1163  		{args: wrapArgs(big.NewInt(123)), want: NewInt(123).ToObject()},
  1164  		{args: wrapArgs(overflowLong), wantExc: mustCreateException(OverflowErrorType, "Python int too large to convert to a Go int")},
  1165  	}
  1166  	for _, cas := range cases {
  1167  		if err := runInvokeTestCase(wrapFuncForTest(ToIntValue), &cas); err != "" {
  1168  			t.Error(err)
  1169  		}
  1170  	}
  1171  }
  1172  
  1173  func TestToNative(t *testing.T) {
  1174  	foo := newObject(ObjectType)
  1175  	cases := []struct {
  1176  		o       *Object
  1177  		want    interface{}
  1178  		wantExc *BaseException
  1179  	}{
  1180  		{True.ToObject(), true, nil},
  1181  		{NewInt(42).ToObject(), 42, nil},
  1182  		{NewStr("bar").ToObject(), "bar", nil},
  1183  		{foo, foo, nil},
  1184  	}
  1185  	for _, cas := range cases {
  1186  		got, raised := ToNative(NewRootFrame(), cas.o)
  1187  		if !exceptionsAreEquivalent(raised, cas.wantExc) {
  1188  			t.Errorf("ToNative(%v) raised %v, want %v", cas.o, raised, cas.wantExc)
  1189  		} else if raised == nil && (!got.IsValid() || !reflect.DeepEqual(got.Interface(), cas.want)) {
  1190  			t.Errorf("ToNative(%v) = %v, want %v", cas.o, got, cas.want)
  1191  		}
  1192  	}
  1193  }
  1194  
  1195  func BenchmarkGetAttr(b *testing.B) {
  1196  	f := NewRootFrame()
  1197  	attr := NewStr("bar")
  1198  	fooType := newTestClass("Foo", []*Type{ObjectType}, NewDict())
  1199  	foo := newObject(fooType)
  1200  	if raised := SetAttr(f, foo, attr, NewInt(123).ToObject()); raised != nil {
  1201  		panic(raised)
  1202  	}
  1203  	b.ResetTimer()
  1204  	for i := 0; i < b.N; i++ {
  1205  		mustNotRaise(GetAttr(f, foo, attr, nil))
  1206  	}
  1207  }
  1208  
  1209  // SetAttr is tested in TestObjectSetAttr.
  1210  
  1211  func exceptionsAreEquivalent(e1 *BaseException, e2 *BaseException) bool {
  1212  	if e1 == nil && e2 == nil {
  1213  		return true
  1214  	}
  1215  	if e1 == nil || e2 == nil {
  1216  		return false
  1217  	}
  1218  	if e1.typ != e2.typ {
  1219  		return false
  1220  	}
  1221  	if e1.args == nil && e2.args == nil {
  1222  		return true
  1223  	}
  1224  	if e1.args == nil || e2.args == nil {
  1225  		return false
  1226  	}
  1227  	f := NewRootFrame()
  1228  	b, raised := IsTrue(f, mustNotRaise(Eq(f, e1.args.ToObject(), e2.args.ToObject())))
  1229  	if raised != nil {
  1230  		panic(raised)
  1231  	}
  1232  	return b
  1233  }
  1234  
  1235  func getFuncName(f interface{}) string {
  1236  	s := runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
  1237  	return regexp.MustCompile(`\w+$`).FindString(s)
  1238  }
  1239  
  1240  // wrapFuncForTest creates a callable object that invokes fun, passing the
  1241  // current frame as its first argument followed by caller provided args.
  1242  func wrapFuncForTest(fun interface{}) *Object {
  1243  	return newBuiltinFunction(getFuncName(fun), func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
  1244  		callable, raised := WrapNative(f, reflect.ValueOf(fun))
  1245  		if raised != nil {
  1246  			return nil, raised
  1247  		}
  1248  		argc := len(args)
  1249  		nativeArgs := make(Args, argc+1, argc+1)
  1250  		nativeArgs[0] = f.ToObject()
  1251  		copy(nativeArgs[1:], args)
  1252  		return callable.Call(f, nativeArgs, nil)
  1253  	}).ToObject()
  1254  }
  1255  
  1256  func mustCreateException(t *Type, msg string) *BaseException {
  1257  	if !t.isSubclass(BaseExceptionType) {
  1258  		panic(fmt.Sprintf("type does not inherit from BaseException: %s", t.Name()))
  1259  	}
  1260  	e := toBaseExceptionUnsafe(newObject(t))
  1261  	if msg == "" {
  1262  		e.args = NewTuple()
  1263  	} else {
  1264  		e.args = NewTuple(NewStr(msg).ToObject())
  1265  	}
  1266  	return e
  1267  }
  1268  
  1269  func mustNotRaise(o *Object, raised *BaseException) *Object {
  1270  	if raised != nil {
  1271  		panic(raised)
  1272  	}
  1273  	return o
  1274  }
  1275  
  1276  var (
  1277  	compareAll = wrapFuncForTest(func(f *Frame, v, w *Object) (*Object, *BaseException) {
  1278  		lt, raised := LT(f, v, w)
  1279  		if raised != nil {
  1280  			return nil, raised
  1281  		}
  1282  		le, raised := LE(f, v, w)
  1283  		if raised != nil {
  1284  			return nil, raised
  1285  		}
  1286  		eq, raised := Eq(f, v, w)
  1287  		if raised != nil {
  1288  			return nil, raised
  1289  		}
  1290  		ne, raised := NE(f, v, w)
  1291  		if raised != nil {
  1292  			return nil, raised
  1293  		}
  1294  		ge, raised := GE(f, v, w)
  1295  		if raised != nil {
  1296  			return nil, raised
  1297  		}
  1298  		gt, raised := GT(f, v, w)
  1299  		if raised != nil {
  1300  			return nil, raised
  1301  		}
  1302  		return NewTuple(lt, le, eq, ne, ge, gt).ToObject(), nil
  1303  	})
  1304  	compareAllResultLT = newTestTuple(true, true, false, true, false, false).ToObject()
  1305  	compareAllResultEq = newTestTuple(false, true, true, false, true, false).ToObject()
  1306  	compareAllResultGT = newTestTuple(false, false, false, true, true, true).ToObject()
  1307  )