Skip to content

Commit da2c4ef

Browse files
miss-islingtonZackerySpytzpganssleserhiy-storchaka
authored
[3.13] gh-87298: Add tests for find_in_strong_cache() bug in _zoneinfo (GH-24829) (GH-136182)
(cherry picked from commit 12ce16b) Co-authored-by: Zackery Spytz <zspytz@gmail.com> Co-authored-by: Paul Ganssle <p.ganssle@gmail.com> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parent 0c439de commit da2c4ef

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

Lib/test/test_zoneinfo/test_zoneinfo.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ def tearDownModule():
5757
shutil.rmtree(TEMP_DIR)
5858

5959

60+
class CustomError(Exception):
61+
pass
62+
63+
6064
class TzPathUserMixin:
6165
"""
6266
Adds a setUp() and tearDown() to make TZPATH manipulations thread-safe.
@@ -403,6 +407,25 @@ def test_time_fixed_offset(self):
403407
self.assertEqual(t.utcoffset(), offset.utcoffset)
404408
self.assertEqual(t.dst(), offset.dst)
405409

410+
def test_cache_exception(self):
411+
class Incomparable(str):
412+
eq_called = False
413+
def __eq__(self, other):
414+
self.eq_called = True
415+
raise CustomError
416+
__hash__ = str.__hash__
417+
418+
key = "America/Los_Angeles"
419+
tz1 = self.klass(key)
420+
key = Incomparable(key)
421+
try:
422+
tz2 = self.klass(key)
423+
except CustomError:
424+
self.assertTrue(key.eq_called)
425+
else:
426+
self.assertFalse(key.eq_called)
427+
self.assertIs(tz2, tz1)
428+
406429

407430
class CZoneInfoTest(ZoneInfoTest):
408431
module = c_zoneinfo
@@ -1506,6 +1529,26 @@ def test_clear_cache_two_keys(self):
15061529
self.assertIsNot(dub0, dub1)
15071530
self.assertIs(tok0, tok1)
15081531

1532+
def test_clear_cache_refleak(self):
1533+
class Stringy(str):
1534+
allow_comparisons = True
1535+
def __eq__(self, other):
1536+
if not self.allow_comparisons:
1537+
raise CustomError
1538+
return super().__eq__(other)
1539+
__hash__ = str.__hash__
1540+
1541+
key = Stringy("America/Los_Angeles")
1542+
self.klass(key)
1543+
key.allow_comparisons = False
1544+
try:
1545+
# Note: This is try/except rather than assertRaises because
1546+
# there is no guarantee that the key is even still in the cache,
1547+
# or that the key for the cache is the original `key` object.
1548+
self.klass.clear_cache(only_keys="America/Los_Angeles")
1549+
except CustomError:
1550+
pass
1551+
15091552

15101553
class CZoneInfoCacheTest(ZoneInfoCacheTest):
15111554
module = c_zoneinfo

0 commit comments

Comments
 (0)