Skip to content

Commit 7595575

Browse files
committed
stdlib/string: first import
1 parent 8ed73c5 commit 7595575

File tree

5 files changed

+193
-0
lines changed

5 files changed

+193
-0
lines changed

stdlib/stdlib.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
_ "github.com/go-python/gpython/stdlib/builtin"
2222
_ "github.com/go-python/gpython/stdlib/math"
23+
_ "github.com/go-python/gpython/stdlib/string"
2324
_ "github.com/go-python/gpython/stdlib/sys"
2425
_ "github.com/go-python/gpython/stdlib/time"
2526
)

stdlib/string/string.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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 string provides the implementation of the python's 'string' module.
6+
package string
7+
8+
import (
9+
"strings"
10+
11+
"github.com/go-python/gpython/py"
12+
)
13+
14+
func init() {
15+
py.RegisterModule(&py.ModuleImpl{
16+
Info: py.ModuleInfo{
17+
Name: "string",
18+
Doc: module_doc,
19+
},
20+
Methods: []*py.Method{
21+
py.MustNewMethod("capwords", capwords, 0, capwords_doc),
22+
},
23+
Globals: py.StringDict{
24+
"whitespace": whitespace,
25+
"ascii_lowercase": ascii_lowercase,
26+
"ascii_uppercase": ascii_uppercase,
27+
"ascii_letters": ascii_letters,
28+
"digits": digits,
29+
"hexdigits": hexdigits,
30+
"octdigits": octdigits,
31+
"punctuation": punctuation,
32+
"printable": printable,
33+
},
34+
})
35+
}
36+
37+
const module_doc = `A collection of string constants.
38+
39+
Public module variables:
40+
41+
whitespace -- a string containing all ASCII whitespace
42+
ascii_lowercase -- a string containing all ASCII lowercase letters
43+
ascii_uppercase -- a string containing all ASCII uppercase letters
44+
ascii_letters -- a string containing all ASCII letters
45+
digits -- a string containing all ASCII decimal digits
46+
hexdigits -- a string containing all ASCII hexadecimal digits
47+
octdigits -- a string containing all ASCII octal digits
48+
punctuation -- a string containing all ASCII punctuation characters
49+
printable -- a string containing all ASCII characters considered printable
50+
`
51+
52+
var (
53+
whitespace = py.String(" \t\n\r\x0b\x0c")
54+
ascii_lowercase = py.String("abcdefghijklmnopqrstuvwxyz")
55+
ascii_uppercase = py.String("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
56+
ascii_letters = ascii_lowercase + ascii_uppercase
57+
digits = py.String("0123456789")
58+
hexdigits = py.String("0123456789abcdefABCDEF")
59+
octdigits = py.String("01234567")
60+
punctuation = py.String("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")
61+
printable = py.String("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c")
62+
)
63+
64+
const capwords_doc = `capwords(s [,sep]) -> string
65+
66+
Split the argument into words using split, capitalize each
67+
word using capitalize, and join the capitalized words using
68+
join. If the optional second argument sep is absent or None,
69+
runs of whitespace characters are replaced by a single space
70+
and leading and trailing whitespace are removed, otherwise
71+
sep is used to split and join the words.`
72+
73+
func capwords(self py.Object, args py.Tuple, kwargs py.StringDict) (py.Object, error) {
74+
var (
75+
pystr py.Object
76+
pysep py.Object = py.None
77+
)
78+
err := py.ParseTupleAndKeywords(args, kwargs, "s|z", []string{"s", "sep"}, &pystr, &pysep)
79+
if err != nil {
80+
return nil, err
81+
}
82+
83+
pystr = py.String(strings.ToLower(string(pystr.(py.String))))
84+
pyvs, err := pystr.(py.String).Split(py.Tuple{pysep}, nil)
85+
if err != nil {
86+
return nil, err
87+
}
88+
89+
var (
90+
lst = pyvs.(*py.List).Items
91+
vs = make([]string, len(lst))
92+
sep = ""
93+
title = func(s string) string {
94+
if s == "" {
95+
return s
96+
}
97+
return strings.ToUpper(s[:1]) + s[1:]
98+
}
99+
)
100+
101+
switch pysep {
102+
case py.None:
103+
for i := range vs {
104+
v := string(lst[i].(py.String))
105+
vs[i] = title(strings.Trim(v, string(whitespace)))
106+
}
107+
sep = " "
108+
default:
109+
sep = string(pysep.(py.String))
110+
for i := range vs {
111+
v := string(lst[i].(py.String))
112+
vs[i] = title(v)
113+
}
114+
}
115+
116+
return py.String(strings.Join(vs, sep)), nil
117+
}

stdlib/string/string_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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 string_test
6+
7+
import (
8+
"testing"
9+
10+
"github.com/go-python/gpython/pytest"
11+
)
12+
13+
func TestString(t *testing.T) {
14+
pytest.RunScript(t, "./testdata/test.py")
15+
}

stdlib/string/testdata/test.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
import string
6+
7+
print("globals:")
8+
for name in ("whitespace",
9+
"ascii_lowercase",
10+
"ascii_uppercase",
11+
"ascii_letters",
12+
"digits",
13+
"hexdigits",
14+
"octdigits",
15+
"punctuation",
16+
"printable"):
17+
v = getattr(string, name)
18+
print("\nstring.%s:\n%s" % (name,repr(v)))
19+
20+
def assertEqual(x, y):
21+
assert x == y, "got: %s, want: %s" % (repr(x), repr(y))
22+
23+
assertEqual(string.capwords('abc def ghi'), 'Abc Def Ghi')
24+
assertEqual(string.capwords('abc\tdef\nghi'), 'Abc Def Ghi')
25+
assertEqual(string.capwords('abc\t def \nghi'), 'Abc Def Ghi')
26+
assertEqual(string.capwords('ABC DEF GHI'), 'Abc Def Ghi')
27+
assertEqual(string.capwords('ABC-DEF-GHI', '-'), 'Abc-Def-Ghi')
28+
assertEqual(string.capwords('ABC-def DEF-ghi GHI'), 'Abc-def Def-ghi Ghi')
29+
assertEqual(string.capwords(' aBc DeF '), 'Abc Def')
30+
assertEqual(string.capwords('\taBc\tDeF\t'), 'Abc Def')
31+
assertEqual(string.capwords('\taBc\tDeF\t', '\t'), '\tAbc\tDef\t')
32+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
globals:
2+
3+
string.whitespace:
4+
' \t\n\r\x0b\x0c'
5+
6+
string.ascii_lowercase:
7+
'abcdefghijklmnopqrstuvwxyz'
8+
9+
string.ascii_uppercase:
10+
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
11+
12+
string.ascii_letters:
13+
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
14+
15+
string.digits:
16+
'0123456789'
17+
18+
string.hexdigits:
19+
'0123456789abcdefABCDEF'
20+
21+
string.octdigits:
22+
'01234567'
23+
24+
string.punctuation:
25+
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
26+
27+
string.printable:
28+
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'

0 commit comments

Comments
 (0)