Skip to content

Commit 78bbe1a

Browse files
committed
Merge pull request #25 from mogproject/develop
add unicode_ljust, unicode_rjust to string module
2 parents 0fb9402 + 1629376 commit 78bbe1a

File tree

3 files changed

+71
-3
lines changed

3 files changed

+71
-3
lines changed

src/mog_commons/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.1.18'
1+
__version__ = '0.1.19'

src/mog_commons/string.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import six
55

66
from mog_commons.collection import distinct
7+
from mog_commons.types import *
78

89
__all__ = [
910
'is_unicode',
@@ -29,6 +30,7 @@ def is_strlike(s):
2930
return isinstance(s, (six.string_types, bytes))
3031

3132

33+
@types(s=String)
3234
def unicode_width(s):
3335
if is_unicode(s):
3436
return sum(__unicode_width_mapping[east_asian_width(c)] for c in s)
@@ -37,6 +39,7 @@ def unicode_width(s):
3739
return len(s)
3840

3941

42+
@types(encoding=Option(String), errors=String)
4043
def to_unicode(s, encoding=None, errors='strict'):
4144
"""
4245
Make unicode string from any value
@@ -58,6 +61,7 @@ def to_unicode(s, encoding=None, errors='strict'):
5861
return str(s)
5962

6063

64+
@types(encoding=Option(String), errors=String)
6165
def to_str(s, encoding=None, errors='strict'):
6266
"""
6367
Make str from any value
@@ -77,6 +81,7 @@ def to_str(s, encoding=None, errors='strict'):
7781
return str(s)
7882

7983

84+
@types(encoding=Option(String), errors=String)
8085
def to_bytes(s, encoding=None, errors='strict'):
8186
"""Convert string to bytes."""
8287
encoding = encoding or 'utf-8'
@@ -92,11 +97,40 @@ def to_bytes(s, encoding=None, errors='strict'):
9297
return str(s).encode(encoding, errors)
9398

9499

95-
def edge_just(left, right, width, fillchar=' '):
96-
padding = fillchar * max(1, width - unicode_width(left + right))
100+
@types(left=String, right=String, width=int, fillchar=String, min_padding_length=int)
101+
def edge_just(left, right, width, fillchar=' ', min_padding_length=1):
102+
"""
103+
:param left:
104+
:param right:
105+
:param width:
106+
:param fillchar:
107+
:param min_padding_length: minimum padding length
108+
:return:
109+
"""
110+
assert unicode_width(fillchar) == 1, 'fillchar must be single-width char'
111+
padding = fillchar * max(min_padding_length, width - unicode_width(left + right))
97112
return left + padding + right
98113

99114

115+
@types(s=String, width=int, fillchar=String)
116+
def unicode_ljust(s, width, fillchar=' '):
117+
"""
118+
Return Unicode string left-justified in a print-length width.
119+
Padding is done using the specified fill character (default is a space).
120+
"""
121+
return edge_just(s, '', width, fillchar, 0)
122+
123+
124+
@types(s=String, width=int, fillchar=String)
125+
def unicode_rjust(s, width, fillchar=' '):
126+
"""
127+
Return Unicode string right-justified in a print-length width.
128+
Padding is done using the specified fill character (default is a space).
129+
"""
130+
return edge_just('', s, width, fillchar, 0)
131+
132+
133+
@types(s=String, width=int)
100134
def unicode_left(s, width):
101135
"""Cut unicode string from left to fit a given width."""
102136
i = 0
@@ -109,6 +143,7 @@ def unicode_left(s, width):
109143
return s[:i]
110144

111145

146+
@types(s=String, width=int)
112147
def unicode_right(s, width):
113148
"""Cut unicode string from right to fit a given width."""
114149
i = len(s)
@@ -121,6 +156,7 @@ def unicode_right(s, width):
121156
return s[i:]
122157

123158

159+
@types(encoding_list=(String, ListOf(String)))
124160
def unicode_decode(data, encoding_list):
125161
"""
126162
Decode string data with one or more encodings, trying sequentially

tests/mog_commons/test_string.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,38 @@ def test_edge_just_unicode(self):
6161
self.assertEqual(string.edge_just('あいu', 'えo', 10), 'あいu えo')
6262
self.assertEqual(string.edge_just('あいう', 'えお', 10), 'あいう えお')
6363

64+
def test_edge_just_error(self):
65+
msg = 'fillchar must be single-width char'
66+
self.assertRaisesMessage(AssertionError, msg, string.edge_just, '', '', 10, '')
67+
self.assertRaisesMessage(AssertionError, msg, string.edge_just, '', '', 10, 'ab')
68+
self.assertRaisesMessage(AssertionError, msg, string.edge_just, '', '', 10, 'あ')
69+
70+
def test_unicode_ljust(self):
71+
self.assertEqual(string.unicode_ljust('', 0), '')
72+
self.assertEqual(string.unicode_ljust('', -1), '')
73+
self.assertEqual(string.unicode_ljust('', 1), ' ')
74+
self.assertEqual(string.unicode_ljust('', 10), ' ')
75+
self.assertEqual(string.unicode_ljust('', 10, '.'), '..........')
76+
self.assertEqual(string.unicode_ljust('abcde', 10), 'abcde ')
77+
self.assertEqual(string.unicode_ljust('abcdefghij', 10), 'abcdefghij')
78+
self.assertEqual(string.unicode_ljust('abcdefghijk', 10), 'abcdefghijk')
79+
self.assertEqual(string.unicode_ljust('あいう', 10), 'あいう ')
80+
self.assertEqual(string.unicode_ljust('あいうe', 10), 'あいうe ')
81+
self.assertEqual(string.unicode_ljust('あいうeお', 10, '*'), 'あいうeお*')
82+
83+
def test_unicode_rjust(self):
84+
self.assertEqual(string.unicode_rjust('', 0), '')
85+
self.assertEqual(string.unicode_rjust('', -1), '')
86+
self.assertEqual(string.unicode_rjust('', 1), ' ')
87+
self.assertEqual(string.unicode_rjust('', 10), ' ')
88+
self.assertEqual(string.unicode_rjust('', 10, '.'), '..........')
89+
self.assertEqual(string.unicode_rjust('abcde', 10), ' abcde')
90+
self.assertEqual(string.unicode_rjust('abcdefghij', 10), 'abcdefghij')
91+
self.assertEqual(string.unicode_rjust('abcdefghijk', 10), 'abcdefghijk')
92+
self.assertEqual(string.unicode_rjust('あいう', 10), ' あいう')
93+
self.assertEqual(string.unicode_rjust('あいうe', 10), ' あいうe')
94+
self.assertEqual(string.unicode_rjust('あいうeお', 10, '*'), '*あいうeお')
95+
6496
def test_unicode_left(self):
6597
self.assertEqual(string.unicode_left('', 3), '')
6698
self.assertEqual(string.unicode_left('abcde', 3), 'abc')

0 commit comments

Comments
 (0)