Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-cachetools for 
openSUSE:Factory checked in at 2026-03-17 19:02:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cachetools (Old)
 and      /work/SRC/openSUSE:Factory/.python-cachetools.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-cachetools"

Tue Mar 17 19:02:03 2026 rev:31 rq:1339019 version:7.0.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cachetools/python-cachetools.changes      
2026-02-17 16:38:58.838434445 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-cachetools.new.8177/python-cachetools.changes
    2026-03-17 19:02:04.742672490 +0100
@@ -1,0 +2,12 @@
+Sat Mar 14 21:59:01 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 7.0.5:
+  * Minor @cachedmethod performance improvements.
+  * Fix and properly document @cachedmethod.cache_key behavior.
+  * Minor documentation improvements.
+  * Fix DeprecationWarning when creating an autospec mock with
+    @cachedmethod decorations.
+  * Provide more efficient clear() implementation for all support
+    Cache classes (courtesy Josep Pon Farreny).
+
+-------------------------------------------------------------------

Old:
----
  cachetools-7.0.1.tar.gz

New:
----
  cachetools-7.0.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-cachetools.spec ++++++
--- /var/tmp/diff_new_pack.80Fq3v/_old  2026-03-17 19:02:06.706753032 +0100
+++ /var/tmp/diff_new_pack.80Fq3v/_new  2026-03-17 19:02:06.722753688 +0100
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-cachetools
-Version:        7.0.1
+Version:        7.0.5
 Release:        0
 Summary:        Extensible memoizing collections and decorators
 License:        MIT

++++++ cachetools-7.0.1.tar.gz -> cachetools-7.0.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/CHANGELOG.rst 
new/cachetools-7.0.5/CHANGELOG.rst
--- old/cachetools-7.0.1/CHANGELOG.rst  2026-02-10 23:12:18.000000000 +0100
+++ new/cachetools-7.0.5/CHANGELOG.rst  2026-03-09 21:27:23.000000000 +0100
@@ -1,3 +1,31 @@
+v7.0.5 (2026-03-09)
+===================
+
+- Minor ``@cachedmethod`` performance improvements.
+
+
+v7.0.4 (2026-03-08)
+===================
+
+- Fix and properly document ``@cachedmethod.cache_key`` behavior.
+
+- Minor documentation improvements.
+
+
+v7.0.3 (2026-03-05)
+===================
+
+- Fix ``DeprecationWarning`` when creating an autospec mock with
+  ``@cachedmethod`` decorations.
+
+
+v7.0.2 (2026-03-02)
+===================
+
+- Provide more efficient ``clear()`` implementation for all support
+  Cache classes (courtesy Josep Pon Farreny).
+
+
 v7.0.1 (2026-02-10)
 ===================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/PKG-INFO 
new/cachetools-7.0.5/PKG-INFO
--- old/cachetools-7.0.1/PKG-INFO       2026-02-10 23:23:51.343722300 +0100
+++ new/cachetools-7.0.5/PKG-INFO       2026-03-09 21:51:16.601176500 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: cachetools
-Version: 7.0.1
+Version: 7.0.5
 Summary: Extensible memoizing collections and decorators
 Author-email: Thomas Kemmer <[email protected]>
 Maintainer-email: Thomas Kemmer <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/docs/index.rst 
new/cachetools-7.0.5/docs/index.rst
--- old/cachetools-7.0.1/docs/index.rst 2026-02-01 19:54:12.000000000 +0100
+++ new/cachetools-7.0.5/docs/index.rst 2026-03-09 21:21:03.000000000 +0100
@@ -370,13 +370,10 @@
           with urllib.request.urlopen(url) as s:
               return s.read()
 
-      # make sure access to cache is synchronized
+      # remove (pop) an individual cached PEP from the cache
+      key = get_pep.cache_key(42)
       with get_pep.cache_lock:
-          get_pep.cache.clear()
-
-      # always use the key function for accessing cache items
-      with get_pep.cache_lock:
-          get_pep.cache.pop(get_pep.cache_key(42), None)
+          get_pep.cache.pop(key, None)
 
    For the common use case of clearing or invalidating the cache, the
    decorator also provides a :func:`cache_clear()` function which
@@ -582,6 +579,15 @@
       >>> peps.get.cache_info()
       CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
 
+      >>> # remove an individual cached PEP from the cache
+      >>> key = peps.get.cache_key(320)
+      >>> with peps.get.cache_lock:
+      ...    del peps.get.cache[key]
+
+      >>> peps.get.cache_info()
+      CacheInfo(hits=3, misses=8, maxsize=32, currsize=7)
+
+      >>> # remove all cached PEPs and clear cache info
       >>> peps.get.cache_clear()
 
       >>> peps.get.cache_info()
@@ -590,8 +596,9 @@
    The `key` function will be called as `key(self, *args, **kwargs)`
    to retrieve a suitable cache key.  Note that the default `key`
    function, :func:`cachetools.keys.methodkey`, ignores its first
-   argument, i.e. :const:`self`.  This has mostly historical reasons,
-   but also ensures that :const:`self` does not have to be hashable.
+   implicit argument, i.e. :const:`self`.  This has mostly historical
+   reasons, but also ensures that :const:`self` does not have to be
+   hashable.
 
    You may provide a different `key` function,
    e.g. :func:`cachetools.keys.hashkey`, if you need :const:`self` to
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/src/cachetools/__init__.py 
new/cachetools-7.0.5/src/cachetools/__init__.py
--- old/cachetools-7.0.1/src/cachetools/__init__.py     2026-02-10 
23:12:18.000000000 +0100
+++ new/cachetools-7.0.5/src/cachetools/__init__.py     2026-03-09 
21:27:23.000000000 +0100
@@ -12,7 +12,7 @@
     "cachedmethod",
 )
 
-__version__ = "7.0.1"
+__version__ = "7.0.5"
 
 import collections
 import collections.abc
@@ -41,6 +41,9 @@
     def pop(self, _key):
         return 1
 
+    def clear(self):
+        pass
+
 
 class Cache(collections.abc.MutableMapping):
     """Mutable mapping to serve as a simple cache or cache base class."""
@@ -134,6 +137,17 @@
             self[key] = value = default
         return value
 
+    # Although the MutableMapping.clear() default implementation works
+    # perfectly well, it calls popitem() in a loop until the cache is
+    # empty, resulting in O(n) complexity.  For large caches, this
+    # becomes a significant performance bottleneck, so we provide an
+    # optimized version for each Cache subclass.
+
+    def clear(self):
+        self.__data.clear()
+        self.__size.clear()
+        self.__currsize = 0
+
     @property
     def maxsize(self):
         """The maximum size of the cache."""
@@ -177,6 +191,10 @@
         else:
             return (key, self.pop(key))
 
+    def clear(self):
+        Cache.clear(self)
+        self.__order.clear()
+
 
 class LFUCache(Cache):
     """Least Frequently Used (LFU) cache implementation."""
@@ -237,6 +255,12 @@
         key = next(iter(curr.keys))  # remove an arbitrary element
         return (key, self.pop(key))
 
+    def clear(self):
+        Cache.clear(self)
+        root = self.__root
+        root.prev = root.next = root
+        self.__links.clear()
+
     def __touch(self, key):
         """Increment use count"""
         link = self.__links[key]
@@ -286,6 +310,10 @@
         else:
             return (key, self.pop(key))
 
+    def clear(self):
+        Cache.clear(self)
+        self.__order.clear()
+
     def __touch(self, key):
         """Mark as recently used"""
         try:
@@ -332,6 +360,11 @@
         else:
             return (key, self.pop(key))
 
+    def clear(self):
+        Cache.clear(self)
+        self.__index.clear()
+        del self.__keys[:]
+
 
 class _TimedCache(Cache):
     """Base class for time aware cache implementations."""
@@ -389,11 +422,6 @@
         """The timer function used by the cache."""
         return self.__timer
 
-    def clear(self):
-        with self.__timer as time:
-            self.expire(time)
-            Cache.clear(self)
-
     def get(self, *args, **kwargs):
         with self.__timer:
             return Cache.get(self, *args, **kwargs)
@@ -406,6 +434,12 @@
         with self.__timer:
             return Cache.setdefault(self, *args, **kwargs)
 
+    def clear(self):
+        # Subclasses must override to also reset their own time-tracking
+        # structures; we do not call expire() here since clear() should
+        # be O(1) regardless of cache contents.
+        Cache.clear(self)
+
 
 class TTLCache(_TimedCache):
     """LRU Cache implementation with per-item time-to-live (TTL) value."""
@@ -536,6 +570,12 @@
             else:
                 return (key, self.pop(key))
 
+    def clear(self):
+        _TimedCache.clear(self)
+        root = self.__root
+        root.prev = root.next = root
+        self.__links.clear()
+
     def __getlink(self, key):
         value = self.__links[key]
         self.__links.move_to_end(key)
@@ -660,6 +700,11 @@
             else:
                 return (key, self.pop(key))
 
+    def clear(self):
+        _TimedCache.clear(self)
+        self.__items.clear()
+        del self.__order[:]
+
     def __getitem(self, key):
         value = self.__items[key]
         self.__items.move_to_end(key)
@@ -703,8 +748,8 @@
 
 
 def cachedmethod(cache, key=keys.methodkey, lock=None, condition=None, 
info=False):
-    """Decorator to wrap a class or instance method with a memoizing
-    callable that saves results in a cache.
+    """Decorator to wrap a method with a memoizing callable that saves
+    results in a cache.
 
     """
     from ._cachedmethod import _wrapper
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/src/cachetools/_cachedmethod.py 
new/cachetools-7.0.5/src/cachetools/_cachedmethod.py
--- old/cachetools-7.0.1/src/cachetools/_cachedmethod.py        2026-02-02 
18:55:59.000000000 +0100
+++ new/cachetools-7.0.5/src/cachetools/_cachedmethod.py        2026-03-09 
21:27:23.000000000 +0100
@@ -23,6 +23,10 @@
     )
 
 
+def _none(_):
+    return None
+
+
 class _WrapperBase:
     """Wrapper base class providing default implementations for properties."""
 
@@ -32,9 +36,9 @@
         functools.update_wrapper(self, method)
         self._obj = obj  # protected
         self.__cache = cache
-        self.__key = key
-        self.__lock = lock
-        self.__cond = cond
+        self.__key = functools.partial(key, obj)
+        self.__lock = lock if lock is not None else _none
+        self.__cond = cond if cond is not None else _none
 
     def __call__(self, *args, **kwargs):
         raise NotImplementedError()  # pragma: no cover
@@ -48,15 +52,15 @@
 
     @property
     def cache_key(self):
-        return self.__key
+        return self.__key  # self._obj passed via functools.partial
 
     @property
     def cache_lock(self):
-        return None if self.__lock is None else self.__lock(self._obj)
+        return self.__lock(self._obj)
 
     @property
     def cache_condition(self):
-        return None if self.__cond is None else self.__cond(self._obj)
+        return self.__cond(self._obj)
 
 
 class _DescriptorBase:
@@ -77,7 +81,12 @@
 
     def __get__(self, obj, objtype=None):
         wrapper = self.Wrapper(obj)
-        if self.__attrname is not None:
+        if obj is None:
+            # Return the wrapper itself without modification when accessed
+            # through the class to support class-level introspection, such
+            # as for mocking with autospec=True in unittest.mock.
+            pass
+        elif self.__attrname is not None:
             # replace descriptor instance with wrapper in instance dict
             try:
                 # In case of a race condition where another thread already 
replaced
@@ -148,7 +157,7 @@
                 cache = self.cache
                 lock = self.cache_lock
                 cond = self.cache_condition
-                key = self.cache_key(self._obj, *args, **kwargs)
+                key = self.cache_key(*args, **kwargs)
 
                 with lock:
                     cond.wait_for(lambda: key not in self.__pending)
@@ -194,7 +203,7 @@
             def __call__(self, *args, **kwargs):
                 cache = self.cache
                 lock = self.cache_lock
-                key = self.cache_key(self._obj, *args, **kwargs)
+                key = self.cache_key(*args, **kwargs)
                 with lock:
                     try:
                         result = cache[key]
@@ -233,7 +242,7 @@
 
             def __call__(self, *args, **kwargs):
                 cache = self.cache
-                key = self.cache_key(self._obj, *args, **kwargs)
+                key = self.cache_key(*args, **kwargs)
                 try:
                     result = cache[key]
                     self.__hits += 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/src/cachetools.egg-info/PKG-INFO 
new/cachetools-7.0.5/src/cachetools.egg-info/PKG-INFO
--- old/cachetools-7.0.1/src/cachetools.egg-info/PKG-INFO       2026-02-10 
23:23:51.000000000 +0100
+++ new/cachetools-7.0.5/src/cachetools.egg-info/PKG-INFO       2026-03-09 
21:51:16.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: cachetools
-Version: 7.0.1
+Version: 7.0.5
 Summary: Extensible memoizing collections and decorators
 Author-email: Thomas Kemmer <[email protected]>
 Maintainer-email: Thomas Kemmer <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/tests/__init__.py 
new/cachetools-7.0.5/tests/__init__.py
--- old/cachetools-7.0.1/tests/__init__.py      2026-02-01 19:54:12.000000000 
+0100
+++ new/cachetools-7.0.5/tests/__init__.py      2026-03-09 21:21:03.000000000 
+0100
@@ -266,6 +266,57 @@
 
         self._test_getsizeof(Cache(maxsize=3))
 
+    def test_clear(self):
+        cache = self.Cache(maxsize=2)
+        cache.update({1: 1, 2: 2})
+
+        self.assertEqual(2, len(cache))
+        self.assertEqual(2, cache.currsize)
+
+        cache.clear()
+
+        self.assertEqual(0, len(cache))
+        self.assertEqual(0, cache.currsize)
+        self.assertNotIn(1, cache)
+        self.assertNotIn(2, cache)
+
+        # verify cache can be reused after clear
+        cache[3] = 3
+        cache[4] = 4
+        self.assertEqual(2, len(cache))
+        self.assertEqual(3, cache[3])
+        self.assertEqual(4, cache[4])
+
+        # verify eviction still works after clear
+        cache[5] = 5
+        self.assertEqual(2, len(cache))
+        self.assertIn(5, cache)
+
+    def test_clear_empty(self):
+        cache = self.Cache(maxsize=2)
+        cache.clear()  # should not raise
+        self.assertEqual(0, len(cache))
+        self.assertEqual(0, cache.currsize)
+
+    def test_clear_getsizeof(self):
+        cache = self.Cache(maxsize=10, getsizeof=lambda x: x)
+        cache[1] = 1
+        cache[2] = 2
+        cache[3] = 3
+
+        self.assertEqual(3, len(cache))
+        self.assertEqual(6, cache.currsize)
+
+        cache.clear()
+
+        self.assertEqual(0, len(cache))
+        self.assertEqual(0, cache.currsize)
+
+        # verify cache can be reused with getsizeof after clear
+        cache[4] = 4
+        self.assertEqual(1, len(cache))
+        self.assertEqual(4, cache.currsize)
+
     def test_pickle(self):
         import pickle
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/tests/test_cachedmethod.py 
new/cachetools-7.0.5/tests/test_cachedmethod.py
--- old/cachetools-7.0.1/tests/test_cachedmethod.py     2026-02-01 
19:54:12.000000000 +0100
+++ new/cachetools-7.0.5/tests/test_cachedmethod.py     2026-03-09 
21:21:03.000000000 +0100
@@ -1,4 +1,5 @@
 import unittest
+import unittest.mock
 import warnings
 
 
@@ -369,24 +370,26 @@
         cached = Cached(cache)
 
         self.assertIs(cached.get.cache, cache)
-        self.assertIs(cached.get.cache_key, keys.methodkey)
         self.assertIs(cached.get.cache_lock, None)
         self.assertIs(cached.get.cache_condition, None)
+        self.assertEqual(cached.get.cache_key(42), keys.methodkey(cached, 42))
 
         self.assertIs(cached.get_lock.cache, cache)
-        self.assertIs(cached.get_lock.cache_key, keys.methodkey)
         self.assertIs(cached.get_lock.cache_lock, cached.lock)
         self.assertIs(cached.get_lock.cache_condition, None)
+        self.assertEqual(cached.get_lock.cache_key(42), keys.methodkey(cached, 
42))
 
         self.assertIs(cached.get_cond.cache, cache)
-        self.assertIs(cached.get_cond.cache_key, keys.methodkey)
         self.assertIs(cached.get_cond.cache_lock, cached.cond)
         self.assertIs(cached.get_cond.cache_condition, cached.cond)
+        self.assertEqual(cached.get_cond.cache_key(42), keys.methodkey(cached, 
42))
 
         self.assertIs(cached.get_lock_cond_info.cache, cache)
-        self.assertIs(cached.get_lock_cond_info.cache_key, keys.methodkey)
         self.assertIs(cached.get_lock_cond_info.cache_lock, cached.lock)
         self.assertIs(cached.get_lock_cond_info.cache_condition, cached.cond)
+        self.assertEqual(
+            cached.get_lock_cond_info.cache_key(42), keys.methodkey(cached, 42)
+        )
 
     def test_decorator_clear(self):
         cache = self.cache(2)
@@ -602,15 +605,25 @@
         self.assertEqual(cached1.get_info.cache_info(), (0, 0, 2, 0))
         self.assertEqual(cached2.get_info.cache_info(), (0, 0, 2, 0))
 
+        # hits/misses are counted by instance
         self.assertEqual(cached1.get_info(0), 0)
-
         self.assertEqual(cached1.get_info.cache_info(), (0, 1, 2, 1))
         self.assertEqual(cached2.get_info.cache_info(), (0, 0, 2, 1))
 
+        # default methodkey discards "self", so results will be shared
+        # across instances
         self.assertEqual(cached2.get_info(0), 0)
-
         self.assertEqual(cached1.get_info.cache_info(), (0, 1, 2, 1))
         self.assertEqual(cached2.get_info.cache_info(), (1, 0, 2, 1))
+        self.assertEqual(cached1.get_info(0), 0)
+        self.assertEqual(cached1.get_info.cache_info(), (1, 1, 2, 1))
+        self.assertEqual(cached2.get_info.cache_info(), (1, 0, 2, 1))
+        self.assertEqual(cached1.get_info(1), 1)
+        self.assertEqual(cached1.get_info.cache_info(), (1, 2, 2, 2))
+        self.assertEqual(cached2.get_info.cache_info(), (1, 0, 2, 2))
+        self.assertEqual(cached2.get_info(1), 1)
+        self.assertEqual(cached1.get_info.cache_info(), (1, 2, 2, 2))
+        self.assertEqual(cached2.get_info.cache_info(), (2, 0, 2, 2))
 
     def test_value_too_large(self):
         cache = self.cache(1, getsizeof=lambda x: x)
@@ -673,3 +686,12 @@
 
         with self.assertRaises(TypeError):
             wrapper.cache_info()
+
+
+class AutospecTest(unittest.TestCase):
+    def test_autospec_no_warnings(self):
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter("always")
+            unittest.mock.create_autospec(Cached, instance=True)
+        self.assertEqual(len(w), 0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/tests/test_lfu.py 
new/cachetools-7.0.5/tests/test_lfu.py
--- old/cachetools-7.0.1/tests/test_lfu.py      2026-02-01 19:44:54.000000000 
+0100
+++ new/cachetools-7.0.5/tests/test_lfu.py      2026-03-09 21:21:03.000000000 
+0100
@@ -64,3 +64,27 @@
         self.assertEqual(cache[1], "updated")
         self.assertIn(3, cache)
         self.assertNotIn(2, cache)
+
+    def test_lfu_clear(self):
+        cache = LFUCache(maxsize=2)
+
+        cache[1] = 1
+        cache[1]  # increment frequency
+        cache[1]  # increment frequency again
+        cache[2] = 2
+
+        cache.clear()
+
+        self.assertEqual(0, len(cache))
+        self.assertEqual(0, cache.currsize)
+
+        # verify LFU frequency tracking is reset after clear
+        cache[3] = 3
+        cache[4] = 4
+        cache[3]  # access 3 to increment frequency
+        cache[5] = 5  # should evict 4 (least frequently used)
+
+        self.assertEqual(2, len(cache))
+        self.assertIn(3, cache)
+        self.assertIn(5, cache)
+        self.assertNotIn(4, cache)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/tests/test_lru.py 
new/cachetools-7.0.5/tests/test_lru.py
--- old/cachetools-7.0.1/tests/test_lru.py      2026-02-01 19:44:54.000000000 
+0100
+++ new/cachetools-7.0.5/tests/test_lru.py      2026-03-09 21:21:03.000000000 
+0100
@@ -66,3 +66,24 @@
         self.assertEqual(cache[1], "updated")
         self.assertIn(3, cache)
         self.assertNotIn(2, cache)
+
+    def test_lru_clear(self):
+        cache = LRUCache(maxsize=2)
+
+        cache[1] = 1
+        cache[2] = 2
+        cache.clear()
+
+        self.assertEqual(0, len(cache))
+        self.assertEqual(0, cache.currsize)
+
+        # verify LRU order is reset after clear
+        cache[3] = 3
+        cache[4] = 4
+        cache[3]  # access 3 to make it most recently used
+        cache[5] = 5  # should evict 4 (least recently used)
+
+        self.assertEqual(2, len(cache))
+        self.assertIn(3, cache)
+        self.assertIn(5, cache)
+        self.assertNotIn(4, cache)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/tests/test_tlru.py 
new/cachetools-7.0.5/tests/test_tlru.py
--- old/cachetools-7.0.1/tests/test_tlru.py     2026-02-10 23:12:18.000000000 
+0100
+++ new/cachetools-7.0.5/tests/test_tlru.py     2026-03-09 21:21:03.000000000 
+0100
@@ -299,3 +299,31 @@
         expired = cache.expire()
         self.assertEqual(4, len(expired))
         self.assertEqual(0, len(cache))
+
+    def test_tlru_clear(self):
+        cache = TLRUCache(maxsize=2, ttu=lambda k, v, t: t + 2, timer=Timer())
+
+        cache[1] = 1
+        cache[2] = 2
+        cache.clear()
+
+        self.assertEqual(0, len(cache))
+        self.assertEqual(0, cache.currsize)
+
+        # verify LRU eviction order is reset after clear
+        cache[3] = 3
+        cache[4] = 4
+        cache[3]  # access 3 to make it most recently used
+        cache[5] = 5  # should evict 4 (least recently used)
+
+        self.assertEqual(2, len(cache))
+        self.assertIn(3, cache)
+        self.assertIn(5, cache)
+        self.assertNotIn(4, cache)
+
+        # verify TLRU expiry still works after clear
+        cache[42] = 42
+        cache.timer.tick()
+        cache.timer.tick()
+        cache.timer.tick()  # past TTL
+        self.assertNotIn(42, cache)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.0.1/tests/test_ttl.py 
new/cachetools-7.0.5/tests/test_ttl.py
--- old/cachetools-7.0.1/tests/test_ttl.py      2026-02-10 23:12:18.000000000 
+0100
+++ new/cachetools-7.0.5/tests/test_ttl.py      2026-03-09 21:21:03.000000000 
+0100
@@ -215,3 +215,31 @@
         items = cache.expire(datetime.now() + timedelta(days=1))
         self.assertEqual([(1, 1)], list(items))
         self.assertEqual(0, len(cache))
+
+    def test_ttl_clear(self):
+        cache = TTLCache(maxsize=2, ttl=2, timer=Timer())
+
+        cache[1] = 1
+        cache[2] = 2
+        cache.clear()
+
+        self.assertEqual(0, len(cache))
+        self.assertEqual(0, cache.currsize)
+
+        # verify LRU eviction order is reset after clear
+        cache[3] = 3
+        cache[4] = 4
+        cache[3]  # access 3 to make it most recently used
+        cache[5] = 5  # should evict 4 (least recently used)
+
+        self.assertEqual(2, len(cache))
+        self.assertIn(3, cache)
+        self.assertIn(5, cache)
+        self.assertNotIn(4, cache)
+
+        # verify TTL expiry still works after clear
+        cache[42] = 42
+        cache.timer.tick()
+        cache.timer.tick()
+        cache.timer.tick()  # past TTL
+        self.assertNotIn(42, cache)

Reply via email to