Title: [279381] trunk/Tools
Revision
279381
Author
jbed...@apple.com
Date
2021-06-29 12:27:13 -0700 (Tue, 29 Jun 2021)

Log Message

[webkitcorepy] Add NestedFuzzyDict
https://bugs.webkit.org/show_bug.cgi?id=227150
<rdar://problem/79475464>

Reviewed by Dewei Zhu.

* Scripts/libraries/webkitcorepy/setup.py: Bump version.
* Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py: Ditto.
* Scripts/libraries/webkitcorepy/webkitcorepy/nested_fuzzy_dict.py: Added.
(NestedFuzzyDict):
(NestedFuzzyDict.assert_valid_key): Ensure that the provided key is fuzz-able.
(NestedFuzzyDict.__init__): Construct the object the same way a dictionary is constructed.
(NestedFuzzyDict.__getitem__): Split provided keyname and fuzzy match the second part.
(NestedFuzzyDict.get): Ditto.
(NestedFuzzyDict.getitem): Return the complete keyname and value.
(NestedFuzzyDict.__setitem__): Add value to dictionary.
(NestedFuzzyDict.update): Given a dictionary, insert it's contents into this object.
(NestedFuzzyDict.keys): Iterate through all keys in the object.
(NestedFuzzyDict.values): Iterate through all values in the object.
(NestedFuzzyDict.items): Iterate through all key/value pairs in the object.
(NestedFuzzyDict.dict): Return a standard dictionary with the contents of this object.
(NestedFuzzyDict.__repr__):
(NestedFuzzyDict.__str__):
* Scripts/libraries/webkitcorepy/webkitcorepy/tests/nested_fuzzy_dict_unittest.py: Added.
(TestNestedFuzzyDict):
(TestNestedFuzzyDict.test_constructor):
(TestNestedFuzzyDict.test_index):
(TestNestedFuzzyDict.test_get):
(TestNestedFuzzyDict.test_getitem):
(TestNestedFuzzyDict.test_set):
(TestNestedFuzzyDict.test_dict):

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (279380 => 279381)


--- trunk/Tools/ChangeLog	2021-06-29 19:07:43 UTC (rev 279380)
+++ trunk/Tools/ChangeLog	2021-06-29 19:27:13 UTC (rev 279381)
@@ -1,5 +1,39 @@
 2021-06-29  Jonathan Bedard  <jbed...@apple.com>
 
+        [webkitcorepy] Add NestedFuzzyDict
+        https://bugs.webkit.org/show_bug.cgi?id=227150
+        <rdar://problem/79475464>
+
+        Reviewed by Dewei Zhu.
+
+        * Scripts/libraries/webkitcorepy/setup.py: Bump version.
+        * Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py: Ditto.
+        * Scripts/libraries/webkitcorepy/webkitcorepy/nested_fuzzy_dict.py: Added.
+        (NestedFuzzyDict):
+        (NestedFuzzyDict.assert_valid_key): Ensure that the provided key is fuzz-able.
+        (NestedFuzzyDict.__init__): Construct the object the same way a dictionary is constructed.
+        (NestedFuzzyDict.__getitem__): Split provided keyname and fuzzy match the second part.
+        (NestedFuzzyDict.get): Ditto.
+        (NestedFuzzyDict.getitem): Return the complete keyname and value.
+        (NestedFuzzyDict.__setitem__): Add value to dictionary.
+        (NestedFuzzyDict.update): Given a dictionary, insert it's contents into this object.
+        (NestedFuzzyDict.keys): Iterate through all keys in the object.
+        (NestedFuzzyDict.values): Iterate through all values in the object.
+        (NestedFuzzyDict.items): Iterate through all key/value pairs in the object.
+        (NestedFuzzyDict.dict): Return a standard dictionary with the contents of this object.
+        (NestedFuzzyDict.__repr__):
+        (NestedFuzzyDict.__str__):
+        * Scripts/libraries/webkitcorepy/webkitcorepy/tests/nested_fuzzy_dict_unittest.py: Added.
+        (TestNestedFuzzyDict):
+        (TestNestedFuzzyDict.test_constructor):
+        (TestNestedFuzzyDict.test_index):
+        (TestNestedFuzzyDict.test_get):
+        (TestNestedFuzzyDict.test_getitem):
+        (TestNestedFuzzyDict.test_set):
+        (TestNestedFuzzyDict.test_dict):
+
+2021-06-29  Jonathan Bedard  <jbed...@apple.com>
+
         [webkitcorepy] Add MeasureTime python tool
         https://bugs.webkit.org/show_bug.cgi?id=227313
         <rdar://problem/79689588>

Modified: trunk/Tools/Scripts/libraries/webkitcorepy/setup.py (279380 => 279381)


--- trunk/Tools/Scripts/libraries/webkitcorepy/setup.py	2021-06-29 19:07:43 UTC (rev 279380)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/setup.py	2021-06-29 19:27:13 UTC (rev 279381)
@@ -30,7 +30,7 @@
 
 setup(
     name='webkitcorepy',
-    version='0.6.1',
+    version='0.7.0',
     description='Library containing various Python support classes and functions.',
     long_description=readme(),
     classifiers=[

Modified: trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py (279380 => 279381)


--- trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py	2021-06-29 19:07:43 UTC (rev 279380)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py	2021-06-29 19:27:13 UTC (rev 279381)
@@ -37,8 +37,9 @@
 from webkitcorepy.task_pool import TaskPool
 from webkitcorepy.credentials import credentials
 from webkitcorepy.measure_time import MeasureTime
+from webkitcorepy.nested_fuzzy_dict import NestedFuzzyDict
 
-version = Version(0, 6, 1)
+version = Version(0, 7, 0)
 
 from webkitcorepy.autoinstall import Package, AutoInstall
 if sys.version_info > (3, 0):

Added: trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/nested_fuzzy_dict.py (0 => 279381)


--- trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/nested_fuzzy_dict.py	                        (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/nested_fuzzy_dict.py	2021-06-29 19:27:13 UTC (rev 279381)
@@ -0,0 +1,115 @@
+# Copyright (C) 2021 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.
+
+from webkitcorepy.string_utils import unicode
+
+
+class NestedFuzzyDict(object):
+    @classmethod
+    def assert_valid_key(cls, key):
+        if not any((isinstance(key, str), isinstance(key, unicode), isinstance(key, bytes))):
+            raise ValueError("'{}' is not a valid key for a NestedDict".format(type(key)))
+
+    def __init__(self, primary_size=None, **kwargs):
+        self.primary_size = int(primary_size or 6)
+        self._data = dict()
+        self.update(dict(**kwargs))
+
+    def getitem(self, keyname, value=None):
+        self.assert_valid_key(keyname)
+        key_a, key_b = keyname[:self.primary_size], keyname[self.primary_size:]
+        found = None
+        for key, result in self._data.get(key_a, dict()).items():
+            if key.startswith(key_b):
+                if found:
+                    raise KeyError("Multiple values match '{}'".format(keyname))
+                found = key_a + key
+                value = result
+        return found, value
+
+    def __getitem__(self, keyname):
+        key, value = self.getitem(keyname)
+        if key:
+            return value
+        raise KeyError(keyname)
+
+    def get(self, keyname, value=None):
+        return self.getitem(keyname, value)[1]
+
+    def __setitem__(self, key, value):
+        self.assert_valid_key(key)
+        self._data.setdefault(key[:self.primary_size], dict())[key[self.primary_size:]] = value
+
+    def __delitem__(self, keyname):
+        self.assert_valid_key(keyname)
+        key_a, key_b = keyname[:self.primary_size], keyname[self.primary_size:]
+        to_remove = []
+        for key, result in self._data.get(key_a, dict()).items():
+            if key.startswith(key_b):
+                to_remove.append(key)
+        if not to_remove:
+            raise KeyError(keyname)
+        for key in to_remove:
+            del self._data[key_a][key]
+        if not self._data.get(key_a, True):
+            del self._data[key_a]
+
+    def __contains__(self, keyname):
+        key_a, key_b = keyname[:self.primary_size], keyname[self.primary_size:]
+        for key, result in self._data.get(key_a, dict()).items():
+            if key.startswith(key_b):
+                return True
+        return False
+
+    def update(self, data):
+        for key, value in data.items():
+            self[key] = value
+
+    def __len__(self):
+        return sum([len(values) for values in self._data.values()])
+
+    def keys(self):
+        for key_a, values in self._data.items():
+            for key_b in values.keys():
+                yield key_a + key_b
+
+    def values(self):
+        for values in self._data.values():
+            for value in values.values():
+                yield value
+
+    def items(self):
+        for key_a, values in self._data.items():
+            for key_b, value in values.items():
+                yield key_a + key_b, value
+
+    def dict(self):
+        result = dict()
+        for key, value in self.items():
+            result[key] = value
+        return result
+
+    def __repr__(self):
+        return self.dict().__repr__()
+
+    def __str__(self):
+        return self.dict().__str__()

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


--- trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/tests/nested_fuzzy_dict_unittest.py	                        (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/tests/nested_fuzzy_dict_unittest.py	2021-06-29 19:27:13 UTC (rev 279381)
@@ -0,0 +1,95 @@
+# Copyright (C) 2021 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 unittest
+
+from webkitcorepy import NestedFuzzyDict
+
+
+class TestNestedFuzzyDict(unittest.TestCase):
+    def test_constructor(self):
+        d = NestedFuzzyDict(value_a=1, value_b=2, other_value=3)
+        self.assertEqual(sorted(list(d.values())), sorted((1, 2, 3)))
+        self.assertEqual(sorted(list(d.keys())), sorted(('value_a', 'value_b', 'other_value')))
+        self.assertEqual(
+            sorted(list(d.items())),
+            sorted((('value_a', 1), ('value_b', 2), ('other_value', 3))),
+        )
+
+    def test_index(self):
+        d = NestedFuzzyDict(value_a=1, value_b=2, other_value=3)
+        self.assertEqual(d['value_a'], 1)
+        self.assertEqual(d['value_b'], 2)
+        self.assertEqual(d['other_'], 3)
+
+        with self.assertRaises(KeyError):
+            self.assertEqual(d['nothing'], None)
+
+        with self.assertRaises(KeyError):
+            self.assertEqual(d['value'], None)
+
+    def test_get(self):
+        d = NestedFuzzyDict(value_a=1, value_b=2, other_value=3)
+        self.assertEqual(d.get('value_a'), 1)
+        self.assertEqual(d.get('value_b'), 2)
+        self.assertEqual(d.get('other_'), 3)
+        self.assertEqual(d.get('nothing'), None)
+
+        with self.assertRaises(KeyError):
+            self.assertEqual(d.get('value_'), None)
+
+    def test_getitem(self):
+        d = NestedFuzzyDict(value_a=1, value_b=2, other_value=3)
+        self.assertEqual(d.getitem('value_a'), ('value_a', 1))
+        self.assertEqual(d.getitem('value_b'), ('value_b', 2))
+        self.assertEqual(d.getitem('other_'), ('other_value', 3))
+        self.assertEqual(d.getitem('nothing'), (None, None))
+
+        with self.assertRaises(KeyError):
+            self.assertEqual(d.getitem('value_'), (None, None))
+
+    def test_set(self):
+        d = NestedFuzzyDict()
+        self.assertEqual(d.get('somelongvalue'), None)
+        d['somelongvalue'] = 1
+        self.assertEqual(d.get('somelongvalue'), 1)
+        self.assertEqual(d.get('somelong'), 1)
+
+    def test_delitem(self):
+        d = NestedFuzzyDict(value_a=1, value_b=2, other_value=3)
+        del d['other_value']
+        self.assertEqual(len(d), 2)
+        del d['value_']
+        self.assertEqual(len(d), 0)
+
+    def test_contains(self):
+        d = NestedFuzzyDict(value_a=1, value_b=2, other_value=3)
+        self.assertTrue('value_a' in d)
+        self.assertTrue('value_' in d)
+        self.assertFalse('content' in d)
+
+    def test_len(self):
+        self.assertEqual(len(NestedFuzzyDict(value_a=1, value_b=2, other_value=3)), 3)
+
+    def test_dict(self):
+        d = NestedFuzzyDict(value_a=1, value_b=2, other_value=3)
+        self.assertDictEqual(d.dict(), dict(value_a=1, value_b=2, other_value=3))
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to