Skip to content

Commit 5e09d19

Browse files
miss-islingtonZackerySpytzpganssleserhiy-storchaka
authored
[3.14] gh-87298: Add tests for find_in_strong_cache() bug in _zoneinfo (GH-24829) (GH-136181)
(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 f152d60 commit 5e09d19

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
@@ -58,6 +58,10 @@ def tearDownModule():
5858
shutil.rmtree(TEMP_DIR)
5959

6060

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

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

408431
class CZoneInfoTest(ZoneInfoTest):
409432
module = c_zoneinfo
@@ -1507,6 +1530,26 @@ def test_clear_cache_two_keys(self):
15071530
self.assertIsNot(dub0, dub1)
15081531
self.assertIs(tok0, tok1)
15091532

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

15111554
class CZoneInfoCacheTest(ZoneInfoCacheTest):
15121555
module = c_zoneinfo

0 commit comments

Comments
 (0)