From df338e331624145dbb30ebfe9175938fae3856f4 Mon Sep 17 00:00:00 2001 From: Kyle Ellrott Date: Fri, 21 Jun 2019 10:46:04 -0700 Subject: [PATCH 1/4] Adding startswith/endswith methods to strings --- py/string.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++ py/tests/string.py | 10 +++++++++ 2 files changed, 63 insertions(+) diff --git a/py/string.go b/py/string.go index 69600149..bcf3f83b 100644 --- a/py/string.go +++ b/py/string.go @@ -100,6 +100,59 @@ 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 { + 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/string.py b/py/tests/string.py index c8bc1118..bba3447c 100644 --- a/py/tests/string.py +++ b/py/tests/string.py @@ -59,6 +59,16 @@ 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") + doc="bool" assert "true" assert not "" From 22c64260815c871e5546213c71d5ccc212220908 Mon Sep 17 00:00:00 2001 From: Kyle Ellrott Date: Fri, 21 Jun 2019 12:01:37 -0700 Subject: [PATCH 2/4] Adding append method to list --- py/list.go | 11 +++++++++++ py/tests/list.py | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/py/list.go b/py/list.go index c509c45b..0a9a79ba 100644 --- a/py/list.go +++ b/py/list.go @@ -13,6 +13,17 @@ 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)") +} + // Type of this List object func (o *List) Type() *Type { return ListType diff --git a/py/tests/list.py b/py/tests/list.py index 887a1bc9..8a69daf1 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,10 @@ 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]" +assertRaises(TypeError, lambda: [].append()) + doc="finished" From 8a52f448dc8ecd6388cb1fa95aa40063f524c8cf Mon Sep 17 00:00:00 2001 From: Kyle Ellrott Date: Fri, 28 Jun 2019 12:19:01 -0700 Subject: [PATCH 3/4] Making str.endwith respond correctly to tuples --- py/string.go | 6 ++++++ py/tests/string.py | 1 + 2 files changed, 7 insertions(+) diff --git a/py/string.go b/py/string.go index bcf3f83b..33d27b6f 100644 --- a/py/string.go +++ b/py/string.go @@ -139,6 +139,12 @@ func init() { 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()) } diff --git a/py/tests/string.py b/py/tests/string.py index bba3447c..8eb3b691 100644 --- a/py/tests/string.py +++ b/py/tests/string.py @@ -68,6 +68,7 @@ class C(): doc="endswith" assert "HELLO THERE".endswith("HERE") assert not "HELLO THERE".endswith("HELL") +assert "HELLO THERE".endswith(("HELL", "HERE")) doc="bool" assert "true" From 4ad78984a17312a1118094b0ba3fb2eaaa46c1da Mon Sep 17 00:00:00 2001 From: Kyle Ellrott Date: Fri, 28 Jun 2019 12:48:13 -0700 Subject: [PATCH 4/4] Adding extend method --- py/list.go | 12 ++++++++++++ py/tests/list.py | 3 +++ 2 files changed, 15 insertions(+) diff --git a/py/list.go b/py/list.go index 0a9a79ba..0c7a7cc2 100644 --- a/py/list.go +++ b/py/list.go @@ -22,6 +22,18 @@ func init() { 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 diff --git a/py/tests/list.py b/py/tests/list.py index 8a69daf1..f959fed2 100644 --- a/py/tests/list.py +++ b/py/tests/list.py @@ -28,6 +28,9 @@ 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"