Skip to content

Commit fa1e212

Browse files
committed
py: fix explicit string split limits and empty separators
1 parent 444ae5e commit fa1e212

3 files changed

Lines changed: 47 additions & 2 deletions

File tree

‎py/string.go‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ func (s String) find(args Tuple) (Object, error) {
695695
func (s String) Split(args Tuple, kwargs StringDict) (Object, error) {
696696
var (
697697
pyval Object = None
698-
pymax Object = Int(-2)
698+
pymax Object = Int(-1)
699699
pyfmt = "|Oi:split"
700700
kwlst = []string{"sep", "maxsplit"}
701701
)
@@ -710,7 +710,14 @@ func (s String) Split(args Tuple, kwargs StringDict) (Object, error) {
710710
)
711711
switch v := pyval.(type) {
712712
case String:
713-
vs = strings.SplitN(string(s), string(v), int(max)+1)
713+
if v == "" {
714+
return nil, ExceptionNewf(ValueError, "empty separator")
715+
}
716+
n := -1
717+
if max >= 0 && max < Int(len(s)) {
718+
n = int(max) + 1
719+
}
720+
vs = strings.SplitN(string(s), string(v), n)
714721
case NoneType:
715722
vs = fieldsN(string(s), int(max))
716723
default:

‎py/string_test.go‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,36 @@ func TestStringLower(t *testing.T) {
144144
})
145145
}
146146
}
147+
148+
func TestStringSplitLimits(t *testing.T) {
149+
for _, limit := range []Int{-100, -2, -1, 0, 1, 2, Int(^uint(0) >> 1)} {
150+
got, err := String("a,b,c").Split(Tuple{String(","), limit}, nil)
151+
if err != nil {
152+
t.Fatal(err)
153+
}
154+
want := Tuple{String("a"), String("b"), String("c")}
155+
if limit == 0 {
156+
want = Tuple{String("a,b,c")}
157+
} else if limit == 1 {
158+
want = Tuple{String("a"), String("b,c")}
159+
}
160+
items := got.(*List).Items
161+
if len(items) != len(want) {
162+
t.Errorf("limit %d: got %v, want %v", limit, items, want)
163+
continue
164+
}
165+
for i := range want {
166+
if items[i] != want[i] {
167+
t.Errorf("limit %d: got %v, want %v", limit, items, want)
168+
}
169+
}
170+
}
171+
for _, s := range []String{"", "abc"} {
172+
for _, limit := range []Int{-1, 0, 1} {
173+
_, err := s.Split(Tuple{String(""), limit}, nil)
174+
if !IsException(ValueError, err) {
175+
t.Errorf("%q split empty with limit %d: %v, want ValueError", s, limit, err)
176+
}
177+
}
178+
}
179+
}

‎py/tests/string.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ class C():
112112

113113
doc="split"
114114
assert ["0","1","2","4"] == list("0,1,2,4".split(","))
115+
assert ['a', 'b', 'c'] == 'a,b,c'.split(',', -1)
116+
assert ['a,b,c'] == 'a,b,c'.split(',', 0)
117+
assert ['a', 'b', 'c'] == 'a,b,c'.split(',', 2147483647)
118+
assertRaisesText(ValueError, "empty separator", lambda: 'abc'.split(''))
119+
assertRaisesText(ValueError, "empty separator", lambda: ''.split('', 0))
115120
assert [""] == list("".split(","))
116121
assert ['a', 'd,c'] == list("a,d,c".split(",",1))
117122
assert ['a', 'd', 'b'] == list(" a d b ".split())

0 commit comments

Comments
 (0)