Skip to content

Commit ab6c445

Browse files
committed
py: add String.find
Updates #139. Signed-off-by: Sebastien Binet <binet@cern.ch>
1 parent 6c9f9e5 commit ab6c445

File tree

2 files changed

+142
-26
lines changed

2 files changed

+142
-26
lines changed

py/string.go

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,43 @@ func fieldsN(s string, n int) []string {
122122
}
123123

124124
func init() {
125+
StringType.Dict["endswith"] = MustNewMethod("endswith", func(self Object, args Tuple) (Object, error) {
126+
selfStr := string(self.(String))
127+
suffix := []string{}
128+
if len(args) > 0 {
129+
if s, ok := args[0].(String); ok {
130+
suffix = append(suffix, string(s))
131+
} else if s, ok := args[0].(Tuple); ok {
132+
for _, t := range s {
133+
if v, ok := t.(String); ok {
134+
suffix = append(suffix, string(v))
135+
}
136+
}
137+
} else {
138+
return nil, ExceptionNewf(TypeError, "endswith first arg must be str, unicode, or tuple, not %s", args[0].Type())
139+
}
140+
} else {
141+
return nil, ExceptionNewf(TypeError, "endswith() takes at least 1 argument (0 given)")
142+
}
143+
for _, s := range suffix {
144+
if strings.HasSuffix(selfStr, s) {
145+
return Bool(true), nil
146+
}
147+
}
148+
return Bool(false), nil
149+
}, 0, "endswith(suffix[, start[, end]]) -> bool")
150+
151+
StringType.Dict["find"] = MustNewMethod("find", func(self Object, args Tuple) (Object, error) {
152+
return self.(String).find(args)
153+
}, 0, `find(...)
154+
S.find(sub[, start[, end]]) -> int
155+
156+
Return the lowest index in S where substring sub is found,
157+
such that sub is contained within S[start:end]. Optional
158+
arguments start and end are interpreted as in slice notation.
159+
160+
Return -1 on failure.`)
161+
125162
StringType.Dict["replace"] = MustNewMethod("replace", func(self Object, args Tuple) (Object, error) {
126163
return self.(String).Replace(args)
127164
}, 0, `replace(self, old, new, count=-1) -> return a copy with all occurrences of substring old replaced by new.
@@ -169,32 +206,6 @@ replaced.`)
169206
return Bool(false), nil
170207
}, 0, "startswith(prefix[, start[, end]]) -> bool")
171208

172-
StringType.Dict["endswith"] = MustNewMethod("endswith", func(self Object, args Tuple) (Object, error) {
173-
selfStr := string(self.(String))
174-
suffix := []string{}
175-
if len(args) > 0 {
176-
if s, ok := args[0].(String); ok {
177-
suffix = append(suffix, string(s))
178-
} else if s, ok := args[0].(Tuple); ok {
179-
for _, t := range s {
180-
if v, ok := t.(String); ok {
181-
suffix = append(suffix, string(v))
182-
}
183-
}
184-
} else {
185-
return nil, ExceptionNewf(TypeError, "endswith first arg must be str, unicode, or tuple, not %s", args[0].Type())
186-
}
187-
} else {
188-
return nil, ExceptionNewf(TypeError, "endswith() takes at least 1 argument (0 given)")
189-
}
190-
for _, s := range suffix {
191-
if strings.HasSuffix(selfStr, s) {
192-
return Bool(true), nil
193-
}
194-
}
195-
return Bool(false), nil
196-
}, 0, "endswith(suffix[, start[, end]]) -> bool")
197-
198209
}
199210

200211
// Type of this object
@@ -578,6 +589,32 @@ func (s String) M__contains__(item Object) (Object, error) {
578589
return NewBool(strings.Contains(string(s), string(needle))), nil
579590
}
580591

592+
func (s String) find(args Tuple) (Object, error) {
593+
var (
594+
pysub Object
595+
pybeg Object = Int(0)
596+
pyend Object = Int(len(s))
597+
pyfmt = "s|ii:find"
598+
)
599+
err := ParseTuple(args, pyfmt, &pysub, &pybeg, &pyend)
600+
if err != nil {
601+
return nil, err
602+
}
603+
604+
var (
605+
beg = int(pybeg.(Int))
606+
end = int(pyend.(Int))
607+
off = s.slice(0, beg, s.len()).len()
608+
str = string(s.slice(beg, end, s.len()))
609+
sub = string(pysub.(String))
610+
idx = strings.Index(str, sub)
611+
)
612+
if idx < 0 {
613+
return Int(idx), nil
614+
}
615+
return Int(off + String(str[:idx]).len()), nil
616+
}
617+
581618
func (s String) Split(args Tuple, kwargs StringDict) (Object, error) {
582619
var (
583620
pyval Object = None

py/string_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2022 The go-python Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package py
6+
7+
import "testing"
8+
9+
func TestStringFind(t *testing.T) {
10+
for _, tc := range []struct {
11+
str string
12+
sub string
13+
beg int
14+
end int
15+
idx int
16+
}{
17+
{
18+
str: "hello world",
19+
sub: "world",
20+
idx: 6,
21+
},
22+
{
23+
str: "hello world",
24+
sub: "o",
25+
idx: 4,
26+
},
27+
{
28+
str: "hello world",
29+
sub: "o",
30+
beg: 5,
31+
idx: 7,
32+
},
33+
{
34+
str: "hello world",
35+
sub: "bye",
36+
idx: -1,
37+
},
38+
{
39+
str: "Hello, 世界",
40+
sub: "界",
41+
idx: 8,
42+
},
43+
{
44+
str: "01234 6789",
45+
sub: " ",
46+
beg: 6,
47+
idx: -1,
48+
},
49+
{
50+
str: "0123456789",
51+
sub: "6",
52+
beg: 1,
53+
end: 6,
54+
idx: -1,
55+
},
56+
{
57+
str: "0123456789",
58+
sub: "6",
59+
beg: 1,
60+
end: 7,
61+
idx: 6,
62+
},
63+
} {
64+
t.Run(tc.str+":"+tc.sub, func(t *testing.T) {
65+
beg := tc.beg
66+
end := tc.end
67+
if end == 0 {
68+
end = len(tc.str)
69+
}
70+
idx, err := String(tc.str).find(Tuple{String(tc.sub), Int(beg), Int(end)})
71+
if err != nil {
72+
t.Fatalf("invalid: %+v", err)
73+
}
74+
if got, want := int(idx.(Int)), tc.idx; got != want {
75+
t.Fatalf("got=%d, want=%d", got, want)
76+
}
77+
})
78+
}
79+
}

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