diff --git a/py/list.go b/py/list.go index c509c45b..0c7a7cc2 100644 --- a/py/list.go +++ b/py/list.go @@ -13,6 +13,29 @@ type List struct { Items []Object } +func init() { + ListType.Dict["append"] = MustNewMethod("append", func(self Object, args Tuple) (Object, error) { + listSelf := self.(*List) + if len(args) != 1 { + return nil, ExceptionNewf(TypeError, "append() takes exactly one argument (%d given)", len(args)) + } + listSelf.Items = append(listSelf.Items, args[0]) + return NoneType{}, nil + }, 0, "append(item)") + + ListType.Dict["extend"] = MustNewMethod("extend", func(self Object, args Tuple) (Object, error) { + listSelf := self.(*List) + if len(args) != 1 { + return nil, ExceptionNewf(TypeError, "append() takes exactly one argument (%d given)", len(args)) + } + if oList, ok := args[0].(*List); ok { + listSelf.Items = append(listSelf.Items, oList.Items...) + } + return NoneType{}, nil + }, 0, "extend([item])") + +} + // Type of this List object func (o *List) Type() *Type { return ListType diff --git a/py/string.go b/py/string.go index 69600149..33d27b6f 100644 --- a/py/string.go +++ b/py/string.go @@ -100,6 +100,65 @@ func init() { } return &o, nil }, 0, "split(sub) -> split string with sub.") + + StringType.Dict["startswith"] = MustNewMethod("startswith", func(self Object, args Tuple) (Object, error) { + selfStr := string(self.(String)) + prefix := []string{} + if len(args) > 0 { + if s, ok := args[0].(String); ok { + prefix = append(prefix, string(s)) + } else if s, ok := args[0].(Tuple); ok { + for _, t := range s { + if v, ok := t.(String); ok { + prefix = append(prefix, string(v)) + } + } + } else { + return nil, ExceptionNewf(TypeError, "startswith first arg must be str, unicode, or tuple, not %s", args[0].Type()) + } + } else { + return nil, ExceptionNewf(TypeError, "startswith() takes at least 1 argument (0 given)") + } + if len(args) > 1 { + if s, ok := args[1].(Int); ok { + selfStr = selfStr[s:len(selfStr)] + } + } + + for _, s := range prefix { + if strings.HasPrefix(selfStr, s) { + return Bool(true), nil + } + } + return Bool(false), nil + }, 0, "startswith(prefix[, start[, end]]) -> bool") + + StringType.Dict["endswith"] = MustNewMethod("endswith", func(self Object, args Tuple) (Object, error) { + selfStr := string(self.(String)) + suffix := []string{} + if len(args) > 0 { + if s, ok := args[0].(String); ok { + suffix = append(suffix, string(s)) + } else if s, ok := args[0].(Tuple); ok { + for _, t := range s { + if v, ok := t.(String); ok { + suffix = append(suffix, string(v)) + } + } + } else { + return nil, ExceptionNewf(TypeError, "endswith first arg must be str, unicode, or tuple, not %s", args[0].Type()) + } + } else { + return nil, ExceptionNewf(TypeError, "endswith() takes at least 1 argument (0 given)") + } + for _, s := range suffix { + if strings.HasSuffix(selfStr, s) { + return Bool(true), nil + } + } + return Bool(false), nil + }, 0, "endswith(suffix[, start[, end]]) -> bool") + } // Type of this object diff --git a/py/tests/list.py b/py/tests/list.py index 887a1bc9..f959fed2 100644 --- a/py/tests/list.py +++ b/py/tests/list.py @@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. +from libtest import assertRaises + doc="str" assert str([]) == "[]" assert str([1,2,3]) == "[1, 2, 3]" @@ -22,4 +24,13 @@ assert idxs[idx] == a[idx][0] assert values[idx] == a[idx][1] +doc="append" +a = [1,2,3] +a.append(4) +assert repr(a) == "[1, 2, 3, 4]" +a = ['a', 'b', 'c'] +a.extend(['d', 'e', 'f']) +assert repr(a) == "['a', 'b', 'c', 'd', 'e', 'f']" +assertRaises(TypeError, lambda: [].append()) + doc="finished" diff --git a/py/tests/string.py b/py/tests/string.py index c8bc1118..8eb3b691 100644 --- a/py/tests/string.py +++ b/py/tests/string.py @@ -59,6 +59,17 @@ class C(): assert not( 1 == "potato") assert 1 != "potato" +doc="startswith" +assert "HELLO THERE".startswith("HELL") +assert not "HELLO THERE".startswith("THERE") +assert "HELLO".startswith("LLO", 2) +assert "HELLO THERE".startswith(("HERE", "HELL")) + +doc="endswith" +assert "HELLO THERE".endswith("HERE") +assert not "HELLO THERE".endswith("HELL") +assert "HELLO THERE".endswith(("HELL", "HERE")) + doc="bool" assert "true" assert not ""