# HG changeset patch # User Gregory Szorc # Date 1536258820 25200 # Node ID b31b01f93b11a1f4b488c069da67bcb4fbb8dcfc # Parent 067f7d2c7d60e08248d323b2b2342668e9e4dee8 util: properly copy lrucachedict instances Previously, copy() only worked if the cache was full. We teach copy() to only copy defined nodes. Differential Revision: https://phab.mercurial-scm.org/D4498 diff -r 067f7d2c7d60 -r b31b01f93b11 mercurial/util.py --- a/mercurial/util.py Thu Sep 06 11:27:25 2018 -0700 +++ b/mercurial/util.py Thu Sep 06 11:33:40 2018 -0700 @@ -1313,11 +1313,19 @@ def copy(self): result = lrucachedict(self._capacity) + + # We copy entries by iterating in oldest-to-newest order so the copy + # has the correct ordering. + + # Find the first non-empty entry. n = self._head.prev - # Iterate in oldest-to-newest order, so the copy has the right ordering + while n.key is _notset and n is not self._head: + n = n.prev + for i in range(len(self._cache)): result[n.key] = n.value n = n.prev + return result def _movetohead(self, node): diff -r 067f7d2c7d60 -r b31b01f93b11 tests/test-lrucachedict.py --- a/tests/test-lrucachedict.py Thu Sep 06 11:27:25 2018 -0700 +++ b/tests/test-lrucachedict.py Thu Sep 06 11:33:40 2018 -0700 @@ -68,12 +68,28 @@ dc = d.copy() self.assertEqual(len(dc), 2) - # TODO this fails - return for key in ('a', 'b'): self.assertIn(key, dc) self.assertEqual(dc[key], 'v%s' % key) + self.assertEqual(len(d), 2) + for key in ('a', 'b'): + self.assertIn(key, d) + self.assertEqual(d[key], 'v%s' % key) + + d['c'] = 'vc' + del d['b'] + dc = d.copy() + self.assertEqual(len(dc), 2) + for key in ('a', 'c'): + self.assertIn(key, dc) + self.assertEqual(dc[key], 'v%s' % key) + + def testcopyempty(self): + d = util.lrucachedict(4) + dc = d.copy() + self.assertEqual(len(dc), 0) + def testcopyfull(self): d = util.lrucachedict(4) d['a'] = 'va'