diff --git a/src/utils/structures.py b/src/utils/structures.py index 4d3e7a623..251edb546 100644 --- a/src/utils/structures.py +++ b/src/utils/structures.py @@ -1,6 +1,6 @@ ### # Copyright (c) 2002-2009, Jeremiah Fincher -# Copyright (c) 2010-2021, Valentin Lorentz +# Copyright (c) 2010-2022, Valentin Lorentz # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -349,7 +349,10 @@ class TimeoutQueue(object): return self.queue.dequeue()[1] def __iter__(self): - # We could _clearOldElements here, but what happens if someone stores + self._clearOldElements() + + # You may think re-checking _getTimeout() after we just called + # _clearOldElements is redundant, but what happens if someone stores # the resulting generator and elements that should've timed out are # yielded? Hmm? What happens then, smarty-pants? for (t, elt) in self.queue: diff --git a/test/test_utils.py b/test/test_utils.py index d3e068f0a..5e8be3c8b 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -1,7 +1,7 @@ ### # Copyright (c) 2002-2005, Jeremiah Fincher # Copyright (c) 2009,2011, James McCoy -# Copyright (c) 2010-2021, Valentin Lorentz +# Copyright (c) 2010-2022, Valentin Lorentz # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -1182,6 +1182,31 @@ class TestTimeoutQueue(SupyTestCase): q.reset() self.assertFalse(1 in q) + def testClean(self): + def iter_and_next(q): + next(iter(q)) + + def contains(q): + 42 in q + + for f in (len, repr, list, iter_and_next, contains): + print(f) + with self.subTest(f=f.__name__): + q = TimeoutQueue(1) + q.enqueue(1) + timeFastForward(0.5) + q.enqueue(2) + + self.assertEqual([x for (_, x) in q.queue], [1, 2]) + f(q) + self.assertEqual([x for (_, x) in q.queue], [1, 2]) + + timeFastForward(0.6) + + self.assertEqual([x for (_, x) in q.queue], [1, 2]) # not cleaned yet + f(q) + self.assertEqual([x for (_, x) in q.queue], [2]) # now it is + class TestCacheDict(SupyTestCase): def testMaxNeverExceeded(self): max = 10