aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_zoneinfo/test_zoneinfo.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_zoneinfo/test_zoneinfo.py')
-rw-r--r--Lib/test/test_zoneinfo/test_zoneinfo.py47
1 files changed, 45 insertions, 2 deletions
diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py b/Lib/test/test_zoneinfo/test_zoneinfo.py
index d2845495c7f..44e87e71c8e 100644
--- a/Lib/test/test_zoneinfo/test_zoneinfo.py
+++ b/Lib/test/test_zoneinfo/test_zoneinfo.py
@@ -58,6 +58,10 @@ def tearDownModule():
shutil.rmtree(TEMP_DIR)
+class CustomError(Exception):
+ pass
+
+
class TzPathUserMixin:
"""
Adds a setUp() and tearDown() to make TZPATH manipulations thread-safe.
@@ -404,6 +408,25 @@ class ZoneInfoTest(TzPathUserMixin, ZoneInfoTestBase):
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
@@ -1507,6 +1530,26 @@ class ZoneInfoCacheTest(TzPathUserMixin, ZoneInfoTestBase):
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
@@ -1915,8 +1958,8 @@ class ExtensionBuiltTest(unittest.TestCase):
def test_cache_location(self):
# The pure Python version stores caches on attributes, but the C
# extension stores them in C globals (at least for now)
- self.assertFalse(hasattr(c_zoneinfo.ZoneInfo, "_weak_cache"))
- self.assertTrue(hasattr(py_zoneinfo.ZoneInfo, "_weak_cache"))
+ self.assertNotHasAttr(c_zoneinfo.ZoneInfo, "_weak_cache")
+ self.assertHasAttr(py_zoneinfo.ZoneInfo, "_weak_cache")
def test_gc_tracked(self):
import gc