-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
gh-87298: Add tests for find_in_strong_cache() bug in _zoneinfo #24829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1f7a1fa
ae1ba75
41298bd
7a4accd
446d058
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -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 @@ 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 | ||||||||
|
@@ -1507,6 +1530,26 @@ def test_clear_cache_two_keys(self): | |||||||
self.assertIsNot(dub0, dub1) | ||||||||
self.assertIs(tok0, tok1) | ||||||||
|
||||||||
def test_clear_cache_refleak(self): | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We may also want to skip this test if |
||||||||
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) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To increase the chance that this actually works:
Suggested change
|
||||||||
key.allow_comparisons = False | ||||||||
try: | ||||||||
# Note: This is try/except rather than assertRaises because | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I realize that I wrote this function, but it kind of bothers me that this can silently become a no-op (and in fact this is silently a no-op for all subclasses |
||||||||
# 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 | ||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently I wrote this function 4 years ago, but coming back to it now it is opaque as heck, so we should probably describe what this test is about.