Skip to content

Commit 09f14d0

Browse files
authored
builtin: Implement builtin sum (#21)
1 parent eaa7d28 commit 09f14d0

File tree

3 files changed

+82
-2
lines changed

3 files changed

+82
-2
lines changed

builtin/builtin.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func init() {
5959
py.MustNewMethod("round", builtin_round, 0, round_doc),
6060
py.MustNewMethod("setattr", builtin_setattr, 0, setattr_doc),
6161
// py.MustNewMethod("sorted", builtin_sorted, 0, sorted_doc),
62-
// py.MustNewMethod("sum", builtin_sum, 0, sum_doc),
62+
py.MustNewMethod("sum", builtin_sum, 0, sum_doc),
6363
// py.MustNewMethod("vars", builtin_vars, 0, vars_doc),
6464
}
6565
globals := py.StringDict{
@@ -709,3 +709,51 @@ Update and return a dictionary containing the current scope's local variables.`
709709
const globals_doc = `globals() -> dictionary
710710
711711
Return the dictionary containing the current scope's global variables.`
712+
713+
const sum_doc = `sum($module, iterable, start=0, /)
714+
--
715+
Return the sum of a \'start\' value (default: 0) plus an iterable of numbers
716+
717+
When the iterable is empty, return the start value.
718+
This function is intended specifically for use with numeric values and may
719+
reject non-numeric types.
720+
`
721+
722+
func builtin_sum(self py.Object, args py.Tuple) (py.Object, error) {
723+
var seq py.Object
724+
var start py.Object
725+
err := py.UnpackTuple(args, nil, "sum", 1, 2, &seq, &start)
726+
if err != nil {
727+
return nil, err
728+
}
729+
if start == nil {
730+
start = py.Int(0)
731+
} else {
732+
switch start.(type) {
733+
case py.Bytes:
734+
return nil, py.ExceptionNewf(py.TypeError, "sum() can't sum bytes [use b''.join(seq) instead]")
735+
case py.String:
736+
return nil, py.ExceptionNewf(py.TypeError, "sum() can't sum strings [use ''.join(seq) instead]")
737+
}
738+
}
739+
740+
iter, err := py.Iter(seq)
741+
if err != nil {
742+
return nil, err
743+
}
744+
745+
for {
746+
item, err := py.Next(iter)
747+
if err != nil {
748+
if py.IsException(py.StopIteration, err) {
749+
break
750+
}
751+
return nil, err
752+
}
753+
start, err = py.Add(start, item)
754+
if err != nil {
755+
return nil, err
756+
}
757+
}
758+
return start, nil
759+
}

builtin/tests/builtin.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,38 @@ class C: pass
159159
assert getattr(c, "potato") == "spud"
160160
assert c.potato == "spud"
161161

162+
doc="sum"
163+
assert sum([1,2,3]) == 6
164+
assert sum([1,2,3], 3) == 9
165+
assert sum((1,2,3)) == 6
166+
assert sum((1,2,3), 3) == 9
167+
assert sum((1, 2.5, 3)) == 6.5
168+
assert sum((1, 2.5, 3), 3) == 9.5
169+
170+
try:
171+
sum([1,2,3], 'hi')
172+
except TypeError as e:
173+
if e.args[0] != "sum() can't sum strings [use ''.join(seq) instead]":
174+
raise
175+
ok = True
176+
assert ok, "TypeError not raised"
177+
178+
try:
179+
sum([1,2,3], b'hi')
180+
except TypeError as e:
181+
if e.args[0] != "sum() can't sum bytes [use b''.join(seq) instead]":
182+
raise
183+
ok = True
184+
assert ok, "TypeError not raised"
185+
186+
try:
187+
sum(['h', 'i'])
188+
except TypeError as e:
189+
if e.args[0] != "unsupported operand type(s) for +: 'int' and 'str'":
190+
raise
191+
ok = True
192+
assert ok, "TypeError not raised"
193+
162194
doc="__import__"
163195
lib = __import__("lib")
164196
assert lib.libfn() == 42

py/string.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222

2323
type String string
2424

25-
var StringType = ObjectType.NewType("string",
25+
var StringType = ObjectType.NewType("str",
2626
`str(object='') -> str
2727
str(bytes_or_buffer[, encoding[, errors]]) -> str
2828

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy