Skip to content

Commit 8a7aec9

Browse files
corona10ncw
authored andcommitted
builtin: Implement builtin function any, all.
1 parent c0de7de commit 8a7aec9

File tree

3 files changed

+95
-2
lines changed

3 files changed

+95
-2
lines changed

builtin/builtin.go

+59-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ func init() {
1919
py.MustNewMethod("__build_class__", builtin___build_class__, 0, build_class_doc),
2020
py.MustNewMethod("__import__", py.InternalMethodImport, 0, import_doc),
2121
py.MustNewMethod("abs", builtin_abs, 0, abs_doc),
22-
// py.MustNewMethod("all", builtin_all, 0, all_doc),
23-
// py.MustNewMethod("any", builtin_any, 0, any_doc),
22+
py.MustNewMethod("all", builtin_all, 0, all_doc),
23+
py.MustNewMethod("any", builtin_any, 0, any_doc),
2424
// py.MustNewMethod("ascii", builtin_ascii, 0, ascii_doc),
2525
// py.MustNewMethod("bin", builtin_bin, 0, bin_doc),
2626
// py.MustNewMethod("callable", builtin_callable, 0, callable_doc),
@@ -225,6 +225,63 @@ func builtin_abs(self, v py.Object) (py.Object, error) {
225225
return py.Abs(v)
226226
}
227227

228+
const all_doc = `all(iterable) -> bool
229+
230+
Return True if bool(x) is True for all values x in the iterable.
231+
If the iterable is empty, return True.
232+
`
233+
234+
func builtin_all(self, seq py.Object) (py.Object, error) {
235+
iter, err := py.Iter(seq)
236+
res := false
237+
if err != nil {
238+
return nil, err
239+
}
240+
for {
241+
item, err := py.Next(iter)
242+
if err != nil {
243+
if py.IsException(py.StopIteration, err) {
244+
break
245+
}
246+
return nil, err
247+
}
248+
if py.ObjectIsTrue(item) {
249+
res = true
250+
} else {
251+
res = false
252+
break
253+
}
254+
}
255+
return py.NewBool(res), nil
256+
}
257+
258+
const any_doc = `any(iterable) -> bool
259+
260+
Return True if bool(x) is True for any x in the iterable.
261+
If the iterable is empty, Py_RETURN_FALSE."`
262+
263+
func builtin_any(self, seq py.Object) (py.Object, error) {
264+
iter, err := py.Iter(seq)
265+
res := false
266+
if err != nil {
267+
return nil, err
268+
}
269+
for {
270+
item, err := py.Next(iter)
271+
if err != nil {
272+
if py.IsException(py.StopIteration, err) {
273+
break
274+
}
275+
return nil, err
276+
}
277+
if py.ObjectIsTrue(item) {
278+
res = true
279+
break
280+
}
281+
}
282+
return py.NewBool(res), nil
283+
}
284+
228285
const round_doc = `round(number[, ndigits]) -> number
229286
230287
Round a number to a given precision in decimal digits (default 0 digits).

builtin/tests/builtin.py

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33
assert abs(10) == 10
44
assert abs(-10) == 10
55

6+
doc="all"
7+
assert all((0,0,0)) == False
8+
assert all((1,1,0)) == False
9+
assert all(["hello", "world"]) == True
10+
assert all([]) == False
11+
12+
doc="any"
13+
assert any((0,0,0)) == False
14+
assert any((1,1,0)) == True
15+
assert any(["hello", "world"]) == True
16+
assert any([]) == False
17+
618
doc="chr"
719
assert chr(65) == "A"
820
assert chr(163) == "£"

py/object.go

+24
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,27 @@ func ObjectRepr(o Object) Object {
1717
// FIXME
1818
return String(fmt.Sprintf("<%s %v>", o.Type().Name, o))
1919
}
20+
21+
// Return whether the object is True or not
22+
func ObjectIsTrue(o Object) bool {
23+
if o == True {
24+
return true
25+
}
26+
if o == False {
27+
return false
28+
}
29+
30+
if o == None {
31+
return false
32+
}
33+
34+
if I, ok := o.(I__bool__); ok {
35+
cmp, err := I.M__bool__()
36+
if err == nil && cmp == True {
37+
return true
38+
} else if err == nil && cmp == False {
39+
return false
40+
}
41+
}
42+
return false
43+
}

0 commit comments

Comments
 (0)