Commit b61ec8f0 authored by Cholerae Hu's avatar Cholerae Hu Committed by Dylan Trotter

[+] implement builtin function callable (#38)

parent f8a9ed35
...@@ -230,6 +230,17 @@ func builtinBin(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) { ...@@ -230,6 +230,17 @@ func builtinBin(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
return NewStr(numberToBase("0b", 2, index)).ToObject(), nil return NewStr(numberToBase("0b", 2, index)).ToObject(), nil
} }
func builtinCallable(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
if raised := checkFunctionArgs(f, "callable", args, ObjectType); raised != nil {
return nil, raised
}
o := args[0]
if call := o.Type().slots.Call; call == nil {
return False.ToObject(), nil
}
return True.ToObject(), nil
}
func builtinChr(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) { func builtinChr(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
if raised := checkFunctionArgs(f, "chr", args, IntType); raised != nil { if raised := checkFunctionArgs(f, "chr", args, IntType); raised != nil {
return nil, raised return nil, raised
...@@ -499,6 +510,7 @@ func init() { ...@@ -499,6 +510,7 @@ func init() {
"abs": newBuiltinFunction("abs", builtinAbs).ToObject(), "abs": newBuiltinFunction("abs", builtinAbs).ToObject(),
"all": newBuiltinFunction("all", builtinAll).ToObject(), "all": newBuiltinFunction("all", builtinAll).ToObject(),
"bin": newBuiltinFunction("bin", builtinBin).ToObject(), "bin": newBuiltinFunction("bin", builtinBin).ToObject(),
"callable": newBuiltinFunction("callable", builtinCallable).ToObject(),
"chr": newBuiltinFunction("chr", builtinChr).ToObject(), "chr": newBuiltinFunction("chr", builtinChr).ToObject(),
"dir": newBuiltinFunction("dir", builtinDir).ToObject(), "dir": newBuiltinFunction("dir", builtinDir).ToObject(),
"False": False.ToObject(), "False": False.ToObject(),
......
...@@ -64,6 +64,12 @@ func TestBuiltinFuncs(t *testing.T) { ...@@ -64,6 +64,12 @@ func TestBuiltinFuncs(t *testing.T) {
return newObject(badNextType), nil return newObject(badNextType), nil
}).ToObject(), }).ToObject(),
})) }))
fooBuiltinFunc := newBuiltinFunction("foo", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
return newTestTuple(NewTuple(args.makeCopy()...), kwargs.makeDict()).ToObject(), nil
}).ToObject()
fooFunc := NewFunction(NewCode("foo", "foo.py", nil, CodeFlagVarArg, func(f *Frame, args []*Object) (*Object, *BaseException) {
return args[0], nil
}), nil)
cases := []struct { cases := []struct {
f string f string
args Args args Args
...@@ -96,6 +102,15 @@ func TestBuiltinFuncs(t *testing.T) { ...@@ -96,6 +102,15 @@ func TestBuiltinFuncs(t *testing.T) {
{f: "bin", args: wrapArgs(0.1), wantExc: mustCreateException(TypeErrorType, "float object cannot be interpreted as an index")}, {f: "bin", args: wrapArgs(0.1), wantExc: mustCreateException(TypeErrorType, "float object cannot be interpreted as an index")},
{f: "bin", args: wrapArgs(1, 2, 3), wantExc: mustCreateException(TypeErrorType, "'bin' requires 1 arguments")}, {f: "bin", args: wrapArgs(1, 2, 3), wantExc: mustCreateException(TypeErrorType, "'bin' requires 1 arguments")},
{f: "bin", args: wrapArgs(newObject(indexType)), want: NewStr("0b1111011").ToObject()}, {f: "bin", args: wrapArgs(newObject(indexType)), want: NewStr("0b1111011").ToObject()},
{f: "callable", args: wrapArgs(fooBuiltinFunc), want: True.ToObject()},
{f: "callable", args: wrapArgs(fooFunc), want: True.ToObject()},
{f: "callable", args: wrapArgs(0), want: False.ToObject()},
{f: "callable", args: wrapArgs(0.1), want: False.ToObject()},
{f: "callable", args: wrapArgs("foo"), want: False.ToObject()},
{f: "callable", args: wrapArgs(newTestDict("foo", 1, "bar", 2)), want: False.ToObject()},
{f: "callable", args: wrapArgs(newTestList(1, 2, 3)), want: False.ToObject()},
{f: "callable", args: wrapArgs(iter), want: False.ToObject()},
{f: "callable", args: wrapArgs(1, 2), wantExc: mustCreateException(TypeErrorType, "'callable' requires 1 arguments")},
{f: "chr", args: wrapArgs(0), want: NewStr("\x00").ToObject()}, {f: "chr", args: wrapArgs(0), want: NewStr("\x00").ToObject()},
{f: "chr", args: wrapArgs(65), want: NewStr("A").ToObject()}, {f: "chr", args: wrapArgs(65), want: NewStr("A").ToObject()},
{f: "chr", args: wrapArgs(300), wantExc: mustCreateException(ValueErrorType, "chr() arg not in range(256)")}, {f: "chr", args: wrapArgs(300), wantExc: mustCreateException(ValueErrorType, "chr() arg not in range(256)")},
......
...@@ -54,3 +54,27 @@ except TypeError as e: ...@@ -54,3 +54,27 @@ except TypeError as e:
assert str(e) == "'int' object is not iterable" assert str(e) == "'int' object is not iterable"
else: else:
raise AssertionError('this was supposed to raise an exception') raise AssertionError('this was supposed to raise an exception')
# callable(x)
assert not callable(1)
assert not callable(0.1)
assert not callable([1, 2, 3])
assert not callable((1, 2, 3))
assert not callable({'foo': 1, 'bar': 2})
assert callable(lambda x: x+1)
def foo(x):
pass
assert callable(foo)
class bar(object):
def __call__(self, *args, **kwargs):
pass
assert callable(bar)
assert callable(bar())
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment