Skip to content

Commit 5558a8b

Browse files
committed
Implemented isinstance
1 parent 0c23b14 commit 5558a8b

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

builtin/builtin.go

+40-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func init() {
4444
// py.MustNewMethod("hex", builtin_hex, 0, hex_doc),
4545
// py.MustNewMethod("id", builtin_id, 0, id_doc),
4646
// py.MustNewMethod("input", builtin_input, 0, input_doc),
47-
// py.MustNewMethod("isinstance", builtin_isinstance, 0, isinstance_doc),
47+
py.MustNewMethod("isinstance", builtin_isinstance, 0, isinstance_doc),
4848
// py.MustNewMethod("issubclass", builtin_issubclass, 0, issubclass_doc),
4949
py.MustNewMethod("iter", builtin_iter, 0, iter_doc),
5050
py.MustNewMethod("len", builtin_len, 0, len_doc),
@@ -826,6 +826,45 @@ object.
826826
The globals and locals are dictionaries, defaulting to the current
827827
globals and locals. If only globals is given, locals defaults to it.`
828828

829+
const isinstance_doc = `isinstance(obj, class_or_tuple) -> bool
830+
831+
Return whether an object is an instance of a class or of a subclass thereof.
832+
833+
A tuple, as in isinstance(x, (A, B, ...)), may be given as the target to
834+
check against. This is equivalent to isinstance(x, A) or isinstance(x, B)
835+
or ... etc.
836+
`
837+
838+
func isinstance(obj py.Object, classOrTuple py.Object) (py.Bool, error) {
839+
switch classOrTuple.(type) {
840+
case py.Tuple:
841+
var class_tuple = classOrTuple.(py.Tuple)
842+
for idx := range class_tuple {
843+
res, _ := isinstance(obj, class_tuple[idx])
844+
if res {
845+
return res, nil
846+
}
847+
}
848+
return false, nil
849+
default:
850+
if classOrTuple.Type().ObjectType != py.TypeType {
851+
return false, py.ExceptionNewf(py.TypeError, "isinstance() arg 2 must be a type or tuple of types")
852+
}
853+
return obj.Type() == classOrTuple, nil
854+
}
855+
}
856+
857+
func builtin_isinstance(self py.Object, args py.Tuple) (py.Object, error) {
858+
var obj py.Object
859+
var classOrTuple py.Object
860+
err := py.UnpackTuple(args, nil, "isinstance", 2, 2, &obj, &classOrTuple)
861+
if err != nil {
862+
return nil, err
863+
}
864+
865+
return isinstance(obj, classOrTuple)
866+
}
867+
829868
const iter_doc = `iter(iterable) -> iterator
830869
iter(callable, sentinel) -> iterator
831870

vm/tests/builtin.py

+10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright 2018 The go-python Authors. All rights reserved.
22
# Use of this source code is governed by a BSD-style
33
# license that can be found in the LICENSE file.
4+
from libtest import assertRaises
45

56
doc="eval"
67
assert eval("1+2") == 3
@@ -65,4 +66,13 @@
6566
else:
6667
assert False, "SyntaxError not raised"
6768

69+
doc="isinstance"
70+
class A:
71+
pass
72+
a = A()
73+
assert True, isinstance(1, (str, tuple, int))
74+
assert True, isinstance(a, (str, (tuple, (A, ))))
75+
assertRaises(TypeError, isinstance, 1, (A, ), "foo")
76+
assertRaises(TypeError, isinstance, 1, [A, "foo"])
77+
6878
doc="finished"

vm/tests/libtest.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2018 The go-python Authors. All rights reserved.
2+
# Use of this source code is governed by a BSD-style
3+
# license that can be found in the LICENSE file.
4+
5+
"""
6+
Simple test harness
7+
"""
8+
9+
def assertRaises(expecting, fn, *args, **kwargs):
10+
"""Check the exception was raised - don't check the text"""
11+
try:
12+
fn(*args, **kwargs)
13+
except expecting as e:
14+
pass
15+
else:
16+
assert False, "%s not raised" % (expecting,)
17+

0 commit comments

Comments
 (0)