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-08-06 16:17:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cachetools (Old)
 and      /work/SRC/openSUSE:Factory/.python-cachetools.new.16738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-cachetools"

Thu Aug  6 16:17:52 2026 rev:35 rq:1369592 version:7.1.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cachetools/python-cachetools.changes      
2026-06-15 19:41:28.714472919 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-cachetools.new.16738/python-cachetools.changes
   2026-08-06 16:17:54.971468357 +0200
@@ -1,0 +2,12 @@
+Tue Aug  4 21:14:43 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 7.1.7:
+  * Improve Cache.__setitem__ behavior when replacing an existing
+    cache item with a larger value.
+  * Update CI environment.
+  * Minor style improvements to keep ruff happy.
+  * Fix TLRUCache silently keeping stale values on expired
+    overwrites.
+  * Reject negative cache item getsizeof values.
+
+-------------------------------------------------------------------

Old:
----
  cachetools-7.1.4.tar.gz

New:
----
  cachetools-7.1.7.tar.gz

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

Other differences:
------------------
++++++ python-cachetools.spec ++++++
--- /var/tmp/diff_new_pack.Vg86Bt/_old  2026-08-06 16:17:55.599490335 +0200
+++ /var/tmp/diff_new_pack.Vg86Bt/_new  2026-08-06 16:17:55.603490475 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-cachetools
-Version:        7.1.4
+Version:        7.1.7
 Release:        0
 Summary:        Extensible memoizing collections and decorators
 License:        MIT

++++++ cachetools-7.1.4.tar.gz -> cachetools-7.1.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/CHANGELOG.rst 
new/cachetools-7.1.7/CHANGELOG.rst
--- old/cachetools-7.1.4/CHANGELOG.rst  2026-05-22 00:35:03.000000000 +0200
+++ new/cachetools-7.1.7/CHANGELOG.rst  2026-08-01 23:18:35.000000000 +0200
@@ -1,3 +1,29 @@
+v7.1.7 (2026-08-01)
+===================
+
+- Improve ``Cache.__setitem__`` behavior when replacing an existing
+  cache item with a larger value.
+
+- Update CI environment.
+
+
+v7.1.6 (2026-07-24)
+===================
+
+- Minor style improvements to keep ``ruff`` happy.
+
+
+v7.1.5 (2026-07-23)
+===================
+
+- Fix ``TLRUCache`` silently keeping stale values on expired
+  overwrites.
+
+- Reject negative cache item ``getsizeof`` values.
+
+- Update build environment.
+
+
 v7.1.4 (2026-05-22)
 ===================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/PKG-INFO 
new/cachetools-7.1.7/PKG-INFO
--- old/cachetools-7.1.4/PKG-INFO       2026-05-22 00:37:58.447413000 +0200
+++ new/cachetools-7.1.7/PKG-INFO       2026-08-01 23:19:52.379794600 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: cachetools
-Version: 7.1.4
+Version: 7.1.7
 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.1.4/docs/conf.py 
new/cachetools-7.1.7/docs/conf.py
--- old/cachetools-7.1.4/docs/conf.py   2026-05-17 21:35:51.000000000 +0200
+++ new/cachetools-7.1.7/docs/conf.py   2026-07-24 00:43:17.000000000 +0200
@@ -1,27 +1,9 @@
-import pathlib
-import sys
-
-src_directory = (pathlib.Path(__file__).parent.parent / "src").resolve()
-sys.path.insert(0, str(src_directory))
-
-
-# Extract the current version from the source.
-def get_version():
-    """Get the version and release from the source code."""
-
-    text = (src_directory / "cachetools/__init__.py").read_text()
-    for line in text.splitlines():
-        if not line.strip().startswith("__version__"):
-            continue
-        full_version = line.partition("=")[2].strip().strip("\"'")
-        partial_version = ".".join(full_version.split(".")[:2])
-        return full_version, partial_version
-    return (None, None)
-
+import importlib.metadata
 
 project = "cachetools"
 copyright = "2014-2026 Thomas Kemmer"
-release, version = get_version()
+release = importlib.metadata.version(project)
+version = ".".join(release.split(".")[:2])
 
 extensions = [
     "sphinx.ext.autodoc",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/pyproject.toml 
new/cachetools-7.1.7/pyproject.toml
--- old/cachetools-7.1.4/pyproject.toml 2026-05-22 00:35:03.000000000 +0200
+++ new/cachetools-7.1.7/pyproject.toml 2026-07-24 00:43:17.000000000 +0200
@@ -52,3 +52,6 @@
 reportFunctionMemberAccess = "information"
 reportOptionalContextManager = "warning"
 reportOptionalMemberAccess = "warning"
+
+[tool.ruff.lint]
+ignore = ["DTZ005", "UP031"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/src/cachetools/__init__.py 
new/cachetools-7.1.7/src/cachetools/__init__.py
--- old/cachetools-7.1.4/src/cachetools/__init__.py     2026-05-22 
00:35:03.000000000 +0200
+++ new/cachetools-7.1.7/src/cachetools/__init__.py     2026-08-01 
23:18:35.000000000 +0200
@@ -12,7 +12,7 @@
     "cachedmethod",
 )
 
-__version__ = "7.1.4"
+__version__ = "7.1.7"
 
 import collections
 import collections.abc
@@ -53,8 +53,8 @@
         if getsizeof:
             self.getsizeof = getsizeof
         if self.getsizeof is not Cache.getsizeof:
-            self.__size = dict()
-        self.__data = dict()
+            self.__size = {}
+        self.__data = {}
         self.__currsize = 0
         self.__maxsize = maxsize
 
@@ -75,15 +75,20 @@
     def __setitem__(self, key, value):
         maxsize = self.__maxsize
         size = self.getsizeof(value)
+        if size < 0:
+            raise ValueError("value size must be non-negative")
         if size > maxsize:
             raise ValueError("value too large")
-        if key not in self.__data or self.__size[key] < size:
-            while self.__currsize + size > maxsize:
+        if key not in self.__data:
+            diffsize = size
+            while self.__currsize + diffsize > maxsize:
                 self.popitem()
-        if key in self.__data:
-            diffsize = size - self.__size[key]
         else:
-            diffsize = size
+            diffsize = size - self.__size[key]
+            while self.__currsize + diffsize > maxsize:
+                self.popitem()
+                if key not in self.__data:
+                    diffsize = size
         self.__data[key] = value
         self.__size[key] = size
         self.__currsize += diffsize
@@ -445,7 +450,7 @@
     """LRU Cache implementation with per-item time-to-live (TTL) value."""
 
     class _Link:
-        __slots__ = ("key", "expires", "next", "prev")
+        __slots__ = ("expires", "key", "next", "prev")
 
         def __init__(self, key=None, expires=None):
             self.key = key
@@ -589,7 +594,7 @@
 
     @functools.total_ordering
     class _Item:
-        __slots__ = ("key", "expires", "removed")
+        __slots__ = ("expires", "key", "removed")
 
         def __init__(self, key=None, expires=None):
             self.key = key
@@ -627,10 +632,12 @@
 
     def __setitem__(self, key, value, cache_setitem=Cache.__setitem__):
         with self.timer as time:
+            self.expire(time)
             expires = self.__ttu(key, value, time)
             if not (time < expires):
-                return  # skip expired items
-            self.expire(time)
+                # updating an existing item with an already expired
+                # one should remove the existing item
+                return self.__delitem(key)
             cache_setitem(self, key, value)
         # removing an existing item would break the heap structure, so
         # only mark it as removed for now
@@ -710,6 +717,14 @@
         self.__items.move_to_end(key)
         return value
 
+    def __delitem(self, key, cache_delitem=Cache.__delitem__):
+        try:
+            self.__items.pop(key).removed = True
+        except KeyError:
+            pass
+        else:
+            cache_delitem(self, key)
+
 
 # note that the runtime __name__ is "CacheInfo", as in stdlib:
 # https://github.com/python/cpython/blob/3.14/Lib/functools.py#L520
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/src/cachetools/func.py 
new/cachetools-7.1.7/src/cachetools/func.py
--- old/cachetools-7.1.4/src/cachetools/func.py 2026-05-17 21:35:51.000000000 
+0200
+++ new/cachetools-7.1.7/src/cachetools/func.py 2026-07-24 00:43:17.000000000 
+0200
@@ -7,9 +7,7 @@
 import time
 from threading import Condition
 
-from . import FIFOCache, LFUCache, LRUCache, RRCache, TTLCache
-from . import cached
-from . import keys
+from . import FIFOCache, LFUCache, LRUCache, RRCache, TTLCache, cached, keys
 
 
 class _UnboundTTLCache(TTLCache):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/src/cachetools/keys.pyi 
new/cachetools-7.1.7/src/cachetools/keys.pyi
--- old/cachetools-7.1.4/src/cachetools/keys.pyi        2026-05-17 
21:35:51.000000000 +0200
+++ new/cachetools-7.1.7/src/cachetools/keys.pyi        2026-07-24 
00:43:17.000000000 +0200
@@ -1,7 +1,8 @@
-from _typeshed import Unused
 from collections.abc import Hashable
 from typing import Final
 
+from _typeshed import Unused
+
 __all__: Final = ("hashkey", "methodkey", "typedkey", "typedmethodkey")
 
 def hashkey(*args: Hashable, **kwargs: Hashable) -> tuple[Hashable, ...]: ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/src/cachetools.egg-info/PKG-INFO 
new/cachetools-7.1.7/src/cachetools.egg-info/PKG-INFO
--- old/cachetools-7.1.4/src/cachetools.egg-info/PKG-INFO       2026-05-22 
00:37:58.000000000 +0200
+++ new/cachetools-7.1.7/src/cachetools.egg-info/PKG-INFO       2026-08-01 
23:19:52.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: cachetools
-Version: 7.1.4
+Version: 7.1.7
 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.1.4/tests/__init__.py 
new/cachetools-7.1.7/tests/__init__.py
--- old/cachetools-7.1.4/tests/__init__.py      2026-05-17 21:35:51.000000000 
+0200
+++ new/cachetools-7.1.7/tests/__init__.py      2026-08-01 23:18:35.000000000 
+0200
@@ -284,6 +284,56 @@
     def test_getsizeof_param(self):
         self._test_getsizeof(self.Cache(maxsize=3, getsizeof=lambda x: x))
 
+    def test_getsizeof_replace_grow(self):
+        cache = self.Cache(maxsize=10, getsizeof=lambda x: x)
+
+        cache[3] = 3
+        cache[4] = 4
+        self.assertEqual(2, len(cache))
+        self.assertEqual(7, cache.currsize)
+
+        # growing an existing entry must only reserve the additional size
+        cache[4] = 7
+        self.assertEqual(2, len(cache))
+        self.assertEqual(10, cache.currsize)
+        self.assertEqual(3, cache[3])
+        self.assertEqual(7, cache[4])
+
+    def test_getsizeof_replace_same_size(self):
+        cache = self.Cache(maxsize=10, getsizeof=lambda x: x)
+
+        cache[3] = 3
+        cache[4] = 4
+        self.assertEqual(7, cache.currsize)
+
+        cache[4] = 4
+        self.assertEqual(2, len(cache))
+        self.assertEqual(7, cache.currsize)
+        self.assertEqual(3, cache[3])
+        self.assertEqual(4, cache[4])
+
+    def test_getsizeof_replace_shrink(self):
+        cache = self.Cache(maxsize=10, getsizeof=lambda x: x)
+
+        cache[3] = 3
+        cache[4] = 4
+        self.assertEqual(7, cache.currsize)
+
+        cache[4] = 1
+        self.assertEqual(2, len(cache))
+        self.assertEqual(4, cache.currsize)
+        self.assertEqual(3, cache[3])
+        self.assertEqual(1, cache[4])
+
+    def test_getsizeof_negative(self):
+        cache = self.Cache(maxsize=3, getsizeof=lambda x: -1)
+
+        with self.assertRaises(ValueError):
+            cache[1] = 1
+
+        self.assertEqual(0, len(cache))
+        self.assertEqual(0, cache.currsize)
+
     def test_getsizeof_subclass(self):
         class Cache(self.Cache):
             @staticmethod
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/tests/test_cached.py 
new/cachetools-7.1.7/tests/test_cached.py
--- old/cachetools-7.1.4/tests/test_cached.py   2026-05-17 21:35:51.000000000 
+0200
+++ new/cachetools-7.1.7/tests/test_cached.py   2026-07-24 00:43:17.000000000 
+0200
@@ -345,7 +345,7 @@
 
 class DictWrapperTest(unittest.TestCase, DecoratorTestMixin):
     def cache(self, minsize):
-        return dict()
+        return {}
 
     def test_decorator_info(self):
         cache = self.cache(2)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/tests/test_cachedmethod.py 
new/cachetools-7.1.7/tests/test_cachedmethod.py
--- old/cachetools-7.1.4/tests/test_cachedmethod.py     2026-05-17 
21:35:51.000000000 +0200
+++ new/cachetools-7.1.7/tests/test_cachedmethod.py     2026-07-24 
00:43:17.000000000 +0200
@@ -2,7 +2,6 @@
 import unittest.mock
 import warnings
 
-
 from cachetools import Cache, cachedmethod, keys
 
 from . import CountedCondition, CountedLock, _TestCaseProtocol
@@ -636,7 +635,7 @@
 
 class DictMethodTest(unittest.TestCase, MethodDecoratorTestMixin):
     def cache(self, minsize, **_kwargs):
-        return dict()
+        return {}
 
 
 class WeakRefMethodTest(unittest.TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/tests/test_func.py 
new/cachetools-7.1.7/tests/test_func.py
--- old/cachetools-7.1.4/tests/test_func.py     2026-05-17 21:35:51.000000000 
+0200
+++ new/cachetools-7.1.7/tests/test_func.py     2026-07-24 00:43:17.000000000 
+0200
@@ -1,5 +1,6 @@
 import unittest
-from typing import Any, Callable
+from collections.abc import Callable
+from typing import Any
 
 import cachetools.func
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/tests/test_threading.py 
new/cachetools-7.1.7/tests/test_threading.py
--- old/cachetools-7.1.4/tests/test_threading.py        2026-05-22 
00:35:03.000000000 +0200
+++ new/cachetools-7.1.7/tests/test_threading.py        2026-07-24 
00:43:17.000000000 +0200
@@ -54,7 +54,7 @@
     def test_cached_stampede(self):
         global count
         count = 0
-        threads = [threading.Thread(target=func) for i in range(0, 
self.NTHREADS)]
+        threads = [threading.Thread(target=func) for i in range(self.NTHREADS)]
         for t in threads:
             t.start()
         for t in threads:
@@ -70,9 +70,7 @@
     def test_cachedmethod_stampede(self):
         self.cache = LRUCache(1)
         self.count = 0
-        threads = [
-            threading.Thread(target=self.method) for i in range(0, 
self.NTHREADS)
-        ]
+        threads = [threading.Thread(target=self.method) for i in 
range(self.NTHREADS)]
         for t in threads:
             t.start()
         for t in threads:
@@ -88,9 +86,7 @@
     def test_cached_locked(self):
         global count
         count = 0
-        threads = [
-            threading.Thread(target=locked_func) for i in range(0, 
self.NTHREADS)
-        ]
+        threads = [threading.Thread(target=locked_func) for i in 
range(self.NTHREADS)]
         for t in threads:
             t.start()
         for t in threads:
@@ -109,7 +105,7 @@
         self.cache = LRUCache(1)
         self.count = 0
         threads = [
-            threading.Thread(target=self.locked_method) for i in range(0, 
self.NTHREADS)
+            threading.Thread(target=self.locked_method) for i in 
range(self.NTHREADS)
         ]
         for t in threads:
             t.start()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/tests/test_tlru.py 
new/cachetools-7.1.7/tests/test_tlru.py
--- old/cachetools-7.1.4/tests/test_tlru.py     2026-05-17 21:35:51.000000000 
+0200
+++ new/cachetools-7.1.7/tests/test_tlru.py     2026-07-23 01:46:46.000000000 
+0200
@@ -144,6 +144,26 @@
         self.assertEqual(cache[4], 4)
         self.assertEqual(cache[5], 5)
 
+    def test_overwrite_existing_with_expired(self):
+        # Overwriting an existing key with an already-expired value must not
+        # silently retain the previous value: the assignment cannot store the
+        # new (dead-on-arrival) value, so the key has to be evicted instead.
+        def ttu(_k, value, t):
+            return t + value
+
+        cache = TLRUCache[int, int, int](maxsize=2, ttu=ttu, timer=Timer())
+        cache[1] = 5
+        self.assertEqual(cache[1], 5)
+        self.assertEqual(len(cache), 1)
+        self.assertEqual(cache.currsize, 1)
+
+        cache[1] = 0  # ttu -> t, i.e. not (t < t): immediately expired
+        self.assertNotIn(1, cache)
+        self.assertIsNone(cache.get(1))
+        self.assertEqual(len(cache), 0)
+        self.assertEqual(cache.currsize, 0)
+        self.assertEqual(set(cache), set())
+
     def test_ttu_expire(self):
         def ttu(_k, _v, t):
             return t + 3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cachetools-7.1.4/tox.ini new/cachetools-7.1.7/tox.ini
--- old/cachetools-7.1.4/tox.ini        2026-05-22 00:35:03.000000000 +0200
+++ new/cachetools-7.1.7/tox.ini        2026-07-24 00:43:17.000000000 +0200
@@ -1,5 +1,5 @@
 [tox]
-envlist = py,docs,doctest,ruff,ruff-format,pyright
+envlist = py,docs,doctest,pyright,ruff,ruff-format
 
 [testenv]
 deps =
@@ -20,23 +20,20 @@
 commands =
      sphinx-build -W -b doctest -d {envtmpdir}/doctrees docs 
{envtmpdir}/doctest
 
+[testenv:pyright]
+deps =
+    pyright
+commands =
+    pyright {posargs}
+
 [testenv:ruff]
 deps =
     ruff
 commands =
     ruff check {posargs}
-skip_install = true
 
 [testenv:ruff-format]
 deps =
     ruff
 commands =
     ruff format --diff -q {posargs}
-skip_install = true
-
-[testenv:pyright]
-deps =
-    pyright
-commands =
-    pyright {posargs}
-skip_install = true

Reply via email to