From 3210ca51592c8318089f585568dfb8aaccfd1c20 Mon Sep 17 00:00:00 2001 From: AN Long Date: Fri, 27 Jun 2025 22:28:05 +0900 Subject: [PATCH] py: implement str.join --- py/string.go | 27 +++++++++++++++++++++++++++ py/tests/string.py | 9 +++++++++ 2 files changed, 36 insertions(+) diff --git a/py/string.go b/py/string.go index e470c01d..a987a11a 100644 --- a/py/string.go +++ b/py/string.go @@ -226,6 +226,9 @@ replaced.`) return self.(String).Lower() }, 0, "lower() -> a copy of the string converted to lowercase") + StringType.Dict["join"] = MustNewMethod("join", func(self Object, args Tuple) (Object, error) { + return self.(String).Join(args) + }, 0, "join(iterable) -> return a string which is the concatenation of the strings in iterable") } // Type of this object @@ -755,6 +758,30 @@ func (s String) Lower() (Object, error) { return String(strings.ToLower(string(s))), nil } +func (s String) Join(args Tuple) (Object, error) { + if len(args) != 1 { + return nil, ExceptionNewf(TypeError, "join() takes exactly one argument (%d given)", len(args)) + } + var parts []string + iterable, err := Iter(args[0]) + if err != nil { + return nil, err + } + item, err := Next(iterable) + for err == nil { + str, ok := item.(String) + if !ok { + return nil, ExceptionNewf(TypeError, "sequence item %d: expected str instance, %s found", len(parts), item.Type().Name) + } + parts = append(parts, string(str)) + item, err = Next(iterable) + } + if err != StopIteration { + return nil, err + } + return String(strings.Join(parts, string(s))), nil +} + // Check stringerface is satisfied var ( _ richComparison = String("") diff --git a/py/tests/string.py b/py/tests/string.py index f2ad6e9b..d1d16cfd 100644 --- a/py/tests/string.py +++ b/py/tests/string.py @@ -905,6 +905,15 @@ def index(s, i): a = "ABC" assert a.lower() == "abc" +doc="join" +assert ",".join(['a', 'b', 'c']) == "a,b,c" +assert " ".join(('a', 'b', 'c')) == "a b c" +assert " ".join("abc") == "a b c" +assert "".join(['a', 'b', 'c']) == "abc" +assert ",".join([]) == "" +assert ",".join(()) == "" +assertRaises(TypeError, lambda: ",".join([1, 2, 3])) + class Index: def __index__(self): return 1