Title: [264715] trunk/Tools
Revision
264715
Author
[email protected]
Date
2020-07-22 11:35:42 -0700 (Wed, 22 Jul 2020)

Log Message

[webkitcorepy] Add string_utils (Part 1)
https://bugs.webkit.org/show_bug.cgi?id=214405

Reviewed by Dewei Zhu.

Centralize handling of unicode encoding/decoding along with various tools
for printing strings.

* Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py:
* Scripts/libraries/webkitcorepy/webkitcorepy/string_utils.py: Added.
(encode): Encode a string as bytes.
(decode): Decode a bytes as a string.
(ordinal): Convert a number to 1st, 2nd, 3rd, 4th, ect.
(pluralize): Convert a string to it's plurlarized version, if provided number indicates
it should be.
(join): Join a list of elements in a human-readable form.
(out_of): Create a fraction which takes up a constant amount of characters.
(elapsed): Describe the amount of time elapsed as a human-readable string.
* Scripts/libraries/webkitcorepy/webkitcorepy/tests/string_utils_unittest.py: Added.
(StringUtils): Test string_utils.
* Scripts/webkitpy/common/unicode_compatibility.py: Replaced with webkitcorepy.string_utils.

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (264714 => 264715)


--- trunk/Tools/ChangeLog	2020-07-22 18:28:32 UTC (rev 264714)
+++ trunk/Tools/ChangeLog	2020-07-22 18:35:42 UTC (rev 264715)
@@ -1,3 +1,27 @@
+2020-07-22  Jonathan Bedard  <[email protected]>
+
+        [webkitcorepy] Add string_utils (Part 1)
+        https://bugs.webkit.org/show_bug.cgi?id=214405
+
+        Reviewed by Dewei Zhu.
+
+        Centralize handling of unicode encoding/decoding along with various tools
+        for printing strings.
+
+        * Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py:
+        * Scripts/libraries/webkitcorepy/webkitcorepy/string_utils.py: Added.
+        (encode): Encode a string as bytes.
+        (decode): Decode a bytes as a string.
+        (ordinal): Convert a number to 1st, 2nd, 3rd, 4th, ect.
+        (pluralize): Convert a string to it's plurlarized version, if provided number indicates
+        it should be.
+        (join): Join a list of elements in a human-readable form.
+        (out_of): Create a fraction which takes up a constant amount of characters.
+        (elapsed): Describe the amount of time elapsed as a human-readable string.
+        * Scripts/libraries/webkitcorepy/webkitcorepy/tests/string_utils_unittest.py: Added.
+        (StringUtils): Test string_utils.
+        * Scripts/webkitpy/common/unicode_compatibility.py: Replaced with webkitcorepy.string_utils.
+
 2020-07-22  Aakash Jain  <[email protected]>
 
         [ews-app] Pass api key in more secure manner

Modified: trunk/Tools/Scripts/libraries/webkitcorepy/README.md (264714 => 264715)


--- trunk/Tools/Scripts/libraries/webkitcorepy/README.md	2020-07-22 18:28:32 UTC (rev 264714)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/README.md	2020-07-22 18:35:42 UTC (rev 264715)
@@ -10,3 +10,16 @@
 from webkitcorepy import Version
 version = Version(1, 2, 3)
 ```
+
+Unicode stream management across Python 2 and 3
+```
+from webkitcorepy import BytesIO, StringIO, UnicodeIO, unicode
+```
+
+Encoding and decoding byte strings and unicode strings
+```
+from webkitcorepy import string_utils
+
+string_utils.encode(...)
+string_utils.decode(...)
+```

Modified: trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py (264714 => 264715)


--- trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py	2020-07-22 18:28:32 UTC (rev 264714)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py	2020-07-22 18:35:42 UTC (rev 264715)
@@ -21,4 +21,6 @@
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 from webkitcorepy.version import Version
-version = Version(0, 0, 1)
+from webkitcorepy.string_utils import BytesIO, StringIO, UnicodeIO, unicode
+
+version = Version(0, 0, 2)

Added: trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/string_utils.py (0 => 264715)


--- trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/string_utils.py	                        (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/string_utils.py	2020-07-22 18:35:42 UTC (rev 264715)
@@ -0,0 +1,102 @@
+# Copyright (C) 2020 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import io
+import sys
+
+BytesIO = io.BytesIO
+if sys.version_info > (3, 0):
+    StringIO = io.StringIO
+else:
+    from StringIO import StringIO
+UnicodeIO = io.StringIO
+
+unicode = str if sys.version_info > (3, 0) else unicode
+
+
+def encode(string, encoding='utf-8', errors='strict', target_type=bytes):
+    if type(string) == unicode and target_type == bytes:
+        return string.encode(encoding, errors=errors)
+    return string
+
+
+def decode(data, encoding='utf-8', errors='strict', target_type=unicode):
+    if type(data) == bytes and target_type == unicode:
+        return data.decode(encoding, errors=errors)
+    return data
+
+
+def ordinal(number):
+    number = int(number)
+    if 10 < number % 100 < 20:
+        return '{}th'.format(number)
+    return '{}{}'.format(
+        number, {
+            1: 'st',
+            2: 'nd',
+            3: 'rd',
+        }.get(number % 10, 'th')
+    )
+
+
+def pluralize(number, string, plural=None):
+    if number == 1:
+        return '1 {}'.format(string)
+    if plural:
+        return '{} {}'.format(number, plural)
+    return '{} {}s'.format(number, string)
+
+
+def join(list, conjunction='and'):
+    if not list:
+        return 'Nothing'
+    if len(list) == 1:
+        return list[0]
+    return '{} {} {}'.format(', '.join(list[:-1]), conjunction, list[-1])
+
+
+def out_of(number, base):
+    number = str(number)
+    base = str(base)
+    return '[{}{}/{}]'.format(' ' * (len(base) - len(number)), number, base)
+
+
+def elapsed(seconds):
+    if seconds <= 0:
+        return 'no time'
+    elif seconds < 1:
+        return 'less than a second'
+
+    seconds = int(round(seconds))
+    minutes = seconds // 60
+    hours = minutes // 60
+    days = hours // 24
+
+    force = False
+    result = ''
+    for value, description in [(days, 'day'), (hours % 24, 'hour'), (minutes % 60, 'minute')]:
+        if force or value:
+            force = True
+            result += ' ' + pluralize(value, description)
+    if force:
+        return result[1:] + ' and ' + pluralize(seconds % 60, 'second')
+    return pluralize(seconds % 60, 'second')

Added: trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/tests/string_utils_unittest.py (0 => 264715)


--- trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/tests/string_utils_unittest.py	                        (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/tests/string_utils_unittest.py	2020-07-22 18:35:42 UTC (rev 264715)
@@ -0,0 +1,82 @@
+# Copyright (C) 2020 Apple Inc. All rights reserved.
+import unittest
+
+from webkitcorepy import BytesIO, StringIO, UnicodeIO, unicode, string_utils
+
+
+class StringUtils(unittest.TestCase):
+    def test_bytesio(self):
+        stream = BytesIO()
+        stream.write(b'bytes data')
+        self.assertEqual(stream.getvalue(), b'bytes data')
+
+    def test_stringio(self):
+        stream = StringIO()
+        stream.write('string data')
+        self.assertEqual(stream.getvalue(), 'string data')
+
+    def test_unicodeio(self):
+        stream = UnicodeIO()
+        stream.write(u'unicod\u00E9 data')
+        self.assertEqual(stream.getvalue(), u'unicod\u00E9 data')
+
+    def test_unicode(self):
+        self.assertEqual(unicode(u'unicode: \u00E9'), u'unicode: \u00E9')
+
+    def test_encode(self):
+        self.assertEqual(string_utils.encode(u'unicode: \u00E9'), b'unicode: \xc3\xa9')
+        self.assertEqual(string_utils.encode(b'bytes data'), b'bytes data')
+
+    def test_decode(self):
+        self.assertEqual(string_utils.decode(u'unicode: \u00E9'), u'unicode: \u00E9')
+        self.assertEqual(string_utils.decode(b'unicode: \xc3\xa9'), u'unicode: \u00E9')
+
+    def test_ordinal(self):
+        self.assertEqual(string_utils.ordinal(0), '0th')
+        self.assertEqual(string_utils.ordinal(1), '1st')
+        self.assertEqual(string_utils.ordinal(2), '2nd')
+        self.assertEqual(string_utils.ordinal(3), '3rd')
+        self.assertEqual(string_utils.ordinal(4), '4th')
+        self.assertEqual(string_utils.ordinal(5), '5th')
+        self.assertEqual(string_utils.ordinal(6), '6th')
+        self.assertEqual(string_utils.ordinal(7), '7th')
+        self.assertEqual(string_utils.ordinal(8), '8th')
+        self.assertEqual(string_utils.ordinal(9), '9th')
+        self.assertEqual(string_utils.ordinal(10), '10th')
+        self.assertEqual(string_utils.ordinal(11), '11th')
+        self.assertEqual(string_utils.ordinal(12), '12th')
+        self.assertEqual(string_utils.ordinal(13), '13th')
+        self.assertEqual(string_utils.ordinal(21), '21st')
+        self.assertEqual(string_utils.ordinal(22), '22nd')
+        self.assertEqual(string_utils.ordinal(23), '23rd')
+        self.assertEqual(string_utils.ordinal(101), '101st')
+        self.assertEqual(string_utils.ordinal(111), '111th')
+
+    def test_pluralize(self):
+        self.assertEqual(string_utils.pluralize(0, 'second'), '0 seconds')
+        self.assertEqual(string_utils.pluralize(1, 'second'), '1 second')
+        self.assertEqual(string_utils.pluralize(2, 'second'), '2 seconds')
+        self.assertEqual(string_utils.pluralize(0, 'mouse', 'mice'), '0 mice')
+        self.assertEqual(string_utils.pluralize(1, 'mouse', 'mice'), '1 mouse')
+        self.assertEqual(string_utils.pluralize(2, 'mouse', 'mice'), '2 mice')
+
+    def test_list(self):
+        self.assertEqual(string_utils.join(['integer', 'string', 'float']), 'integer, string and float')
+        self.assertEqual(string_utils.join(['integer', 'string']), 'integer and string')
+        self.assertEqual(string_utils.join(['integer']), 'integer')
+        self.assertEqual(string_utils.join([]), 'Nothing')
+        self.assertEqual(string_utils.join(['integer', 'string'], conjunction='or'), 'integer or string')
+
+    def test_outof(self):
+        self.assertEqual(string_utils.out_of(1, 3), '[1/3]')
+        self.assertEqual(string_utils.out_of(1, 10), '[ 1/10]')
+        self.assertEqual(string_utils.out_of(10, 10), '[10/10]')
+
+    def test_elapsed(self):
+        self.assertEqual(string_utils.elapsed(0), 'no time')
+        self.assertEqual(string_utils.elapsed(.5), 'less than a second')
+        self.assertEqual(string_utils.elapsed(1), '1 second')
+        self.assertEqual(string_utils.elapsed(4), '4 seconds')
+        self.assertEqual(string_utils.elapsed(74), '1 minute and 14 seconds')
+        self.assertEqual(string_utils.elapsed(3 * 60 * 60), '3 hours 0 minutes and 0 seconds')
+        self.assertEqual(string_utils.elapsed(24 * 60 * 60 + 60 * 60 + 4 * 60 + 5), '1 day 1 hour 4 minutes and 5 seconds')

Modified: trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/version.py (264714 => 264715)


--- trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/version.py	2020-07-22 18:28:32 UTC (rev 264714)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/version.py	2020-07-22 18:35:42 UTC (rev 264715)
@@ -20,10 +20,9 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import collections
 import re
 
-from functools import total_ordering
+from webkitcorepy.string_utils import unicode
 
 
 class Version(object):

Modified: trunk/Tools/Scripts/webkitpy/common/unicode_compatibility.py (264714 => 264715)


--- trunk/Tools/Scripts/webkitpy/common/unicode_compatibility.py	2020-07-22 18:28:32 UTC (rev 264714)
+++ trunk/Tools/Scripts/webkitpy/common/unicode_compatibility.py	2020-07-22 18:35:42 UTC (rev 264715)
@@ -1,4 +1,4 @@
-# Copyright (C) 2019 Apple Inc. All rights reserved.
+# Copyright (C) 2019-2020 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -20,48 +20,19 @@
 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import io
-import sys
+from webkitcorepy import UnicodeIO, StringIO, BytesIO, unicode, string_utils
 
-
-BytesIO = io.BytesIO
-if sys.version_info > (3, 0):
-    StringIO = io.StringIO
-else:
-    from StringIO import StringIO
-UnicodeIO = io.StringIO
-
-unicode = str if sys.version_info > (3, 0) else unicode
-
-
 def encode_if_necessary(value, encoding='utf-8', errors='strict'):
-    # In Python 3, string types must be encoded
-    if type(value) == unicode:
-        return value.encode(encoding, errors=errors)
-    return value
+    return string_utils.encode(value, encoding=encoding, errors=errors)
 
 
 def encode_for(value, target_type, **kwargs):
-    if target_type == bytes:
-        return encode_if_necessary(value, **kwargs)
+    return string_utils.encode(value, target_type=target_type, **kwargs)
 
-    if sys.version_info < (3, 0) and target_type == str:
-        return encode_if_necessary(value, **kwargs)
-    return value
 
-
 def decode_if_necessary(value, encoding='utf-8', errors='strict'):
-    # In Python 2, string types might need to be decoded
-    if type(value) == bytes:
-        return value.decode(encoding, errors=errors)
-    return value
+    return string_utils.decode(value, encoding=encoding, errors=errors)
 
 
 def decode_for(value, target_type):
-    if value is None:
-        return None
-    if type(value) == target_type:
-        return value
-    if target_type == unicode:
-        return decode_if_necessary(bytes(value))
-    return value
+    return string_utils.decode(value, target_type=target_type)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to