https://github.com/python/cpython/commit/da2c4ef7eb4ec2bf7615073b6636b9192222d92b
commit: da2c4ef7eb4ec2bf7615073b6636b9192222d92b
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-07-01T15:19:39Z
summary:

[3.13] gh-87298: Add tests for find_in_strong_cache() bug in _zoneinfo 
(GH-24829) (GH-136182)

(cherry picked from commit 12ce16bc134a602d2ac8acde86ae69f70183cb9f)

Co-authored-by: Zackery Spytz <[email protected]>
Co-authored-by: Paul Ganssle <[email protected]>
Co-authored-by: Serhiy Storchaka <[email protected]>

files:
M Lib/test/test_zoneinfo/test_zoneinfo.py

diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py 
b/Lib/test/test_zoneinfo/test_zoneinfo.py
index f687f29c2224ea..d51736e34c60fc 100644
--- a/Lib/test/test_zoneinfo/test_zoneinfo.py
+++ b/Lib/test/test_zoneinfo/test_zoneinfo.py
@@ -57,6 +57,10 @@ def tearDownModule():
     shutil.rmtree(TEMP_DIR)
 
 
+class CustomError(Exception):
+    pass
+
+
 class TzPathUserMixin:
     """
     Adds a setUp() and tearDown() to make TZPATH manipulations thread-safe.
@@ -403,6 +407,25 @@ def test_time_fixed_offset(self):
                 self.assertEqual(t.utcoffset(), offset.utcoffset)
                 self.assertEqual(t.dst(), offset.dst)
 
+    def test_cache_exception(self):
+        class Incomparable(str):
+            eq_called = False
+            def __eq__(self, other):
+                self.eq_called = True
+                raise CustomError
+            __hash__ = str.__hash__
+
+        key = "America/Los_Angeles"
+        tz1 = self.klass(key)
+        key = Incomparable(key)
+        try:
+            tz2 = self.klass(key)
+        except CustomError:
+            self.assertTrue(key.eq_called)
+        else:
+            self.assertFalse(key.eq_called)
+            self.assertIs(tz2, tz1)
+
 
 class CZoneInfoTest(ZoneInfoTest):
     module = c_zoneinfo
@@ -1506,6 +1529,26 @@ def test_clear_cache_two_keys(self):
         self.assertIsNot(dub0, dub1)
         self.assertIs(tok0, tok1)
 
+    def test_clear_cache_refleak(self):
+        class Stringy(str):
+            allow_comparisons = True
+            def __eq__(self, other):
+                if not self.allow_comparisons:
+                    raise CustomError
+                return super().__eq__(other)
+            __hash__ = str.__hash__
+
+        key = Stringy("America/Los_Angeles")
+        self.klass(key)
+        key.allow_comparisons = False
+        try:
+            # Note: This is try/except rather than assertRaises because
+            # there is no guarantee that the key is even still in the cache,
+            # or that the key for the cache is the original `key` object.
+            self.klass.clear_cache(only_keys="America/Los_Angeles")
+        except CustomError:
+            pass
+
 
 class CZoneInfoCacheTest(ZoneInfoCacheTest):
     module = c_zoneinfo

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to