Skip to content

Commit 35c7a6c

Browse files
committed
Implemented isinstance
1 parent 0c23b14 commit 35c7a6c

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

builtin/builtin.go

+45-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,50 @@ 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(args py.Tuple) (py.Bool, error) {
839+
switch args[1].(type) {
840+
case py.Tuple:
841+
{
842+
var res py.Bool
843+
var class = args[1].(py.Tuple)
844+
for idx := range class {
845+
var new_args []py.Object
846+
new_args = append(new_args, args[0], class[idx])
847+
temp, err := isinstance(new_args)
848+
if err != nil {
849+
return false, err
850+
}
851+
res = res || temp
852+
}
853+
return res, nil
854+
}
855+
default:
856+
{
857+
if args[0].Type() != py.TypeType {
858+
return false, py.ExceptionNewf(py.TypeError, "isinstance() arg 2 must be a type or tuple of types")
859+
}
860+
return args[0].Type() == args[1], nil
861+
}
862+
}
863+
}
864+
865+
func builtin_isinstance(self py.Object, args py.Tuple) (py.Object, error) {
866+
if len(args) > 2 {
867+
return nil, py.ExceptionNewf(py.TypeError, "isinstance expected 2 arguments, got %d", len(args))
868+
}
869+
870+
return isinstance(args)
871+
}
872+
829873
const iter_doc = `iter(iterable) -> iterator
830874
iter(callable, sentinel) -> iterator
831875

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ require (
44
github.com/gopherjs/gopherwasm v1.0.0 // indirect
55
github.com/peterh/liner v1.1.0
66
)
7+
8+
go 1.13

vm/tests/builtin.py

+21
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,25 @@
6565
else:
6666
assert False, "SyntaxError not raised"
6767

68+
doc="isinstance"
69+
class A:
70+
pass
71+
a = A()
72+
assert True, isinstance(1, (str, tuple, int))
73+
assert True, isinstance(a, (str, (tuple, (A, ))))
74+
75+
try:
76+
isinstance(1, (A, ), "foo")
77+
except TypeError:
78+
pass
79+
else:
80+
assert False, "TypeError not raised"
81+
82+
try:
83+
isinstance(1, (A, "foo"))
84+
except TypeError:
85+
pass
86+
else:
87+
assert False, "TypeError not raised"
88+
6889
doc="finished"

0 commit comments

Comments
 (0)