[utils] Fixes compatiblity of QueryCache with expected dict interface
authorLaurent Wouters <lwouters@cenotelie.fr>
Wed, 25 Apr 2018 15:29:25 +0200
changeset 12308 cbbcfa69a0e7
parent 12307 d507cbe169ab
child 12309 48e763ad3b3f
[utils] Fixes compatiblity of QueryCache with expected dict interface QueryCache is expected to mimick the interface of the dict built-in. The current __iter__ implementation breaks this expectation by iterating over key, value pairs instead of only the keys. This changeset fixes this issue by changing the __iter__ implementation to iterate over the keys in the cache and providing an implementation of the items method with a contract identical to the dict build-in (return a copy of the key- value pairs within the dictionary as a list).
cubicweb/test/unittest_utils.py
cubicweb/utils.py
--- a/cubicweb/test/unittest_utils.py	Tue Apr 24 15:21:18 2018 +0200
+++ b/cubicweb/test/unittest_utils.py	Wed Apr 25 15:29:25 2018 +0200
@@ -154,8 +154,28 @@
             v = c.get(x, -1)
             self.assertEqual(v, -1)
 
+    def test_iterkeys(self):
+        """
+        Tests the iterating on keys in the cache
+        """
+        c = QueryCache(ceiling=20)
+        # set 10 values
+        for x in range(10):
+            c[x] = x
+        # arrange for the first 5 to be permanent
+        for x in range(5):
+            for r in range(QueryCache._maxlevel + 2):
+                v = c[x]
+                self.assertEqual(v, x)
+        self.assertEqual(c._usage_report(),
+                         {'transientcount': 0,
+                          'itemcount': 10,
+                          'permanentcount': 5})
+        keys = sorted(c)
+        for x in range(10):
+            self.assertEquals(x, keys[x])
 
-    def test_iterator(self):
+    def test_items(self):
         """
         Tests the iterating on key-value couples in the cache
         """
@@ -172,7 +192,7 @@
                          {'transientcount': 0,
                           'itemcount': 10,
                           'permanentcount': 5})
-        content = sorted(c)
+        content = sorted(c.items())
         for x in range(10):
             self.assertEquals(x, content[x][0])
             self.assertEquals(x, content[x][1])
--- a/cubicweb/utils.py	Tue Apr 24 15:21:18 2018 +0200
+++ b/cubicweb/utils.py	Wed Apr 25 15:29:25 2018 +0200
@@ -627,6 +627,12 @@
         with self._lock:
             return len(self._data)
 
+    def items(self):
+        """Get an iterator over the dictionary's items: (key, value) pairs"""
+        with self._lock:
+            for k, v in self._data.items():
+                yield k, v
+
     def get(self, k, default=None):
         """Get the value associated to the specified key
 
@@ -641,8 +647,8 @@
 
     def __iter__(self):
         with self._lock:
-            for k, v in self._data.items():
-                yield k, v
+            for k in iter(self._data):
+                yield k
 
     def __getitem__(self, k):
         with self._lock: