Change the TimestampStrings check to check for str instead of not ZoneInfo.

This fixes the pytest problem which threw:
TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union

during Mocking
This commit is contained in:
Clemens Schwaighofer
2025-09-25 15:36:47 +09:00
parent ca0ab2d7d1
commit bb60a570d0
4 changed files with 51 additions and 11 deletions

View File

@@ -28,7 +28,7 @@ class TimestampStrings:
self.time_zone = time_zone if time_zone is not None else self.TIME_ZONE self.time_zone = time_zone if time_zone is not None else self.TIME_ZONE
try: try:
self.timestamp_now_tz = datetime.now( self.timestamp_now_tz = datetime.now(
ZoneInfo(self.time_zone) if not isinstance(self.time_zone, ZoneInfo) else self.time_zone ZoneInfo(self.time_zone) if isinstance(self.time_zone, str) else self.time_zone
) )
except ZoneInfoNotFoundError as e: except ZoneInfoNotFoundError as e:
raise ValueError(f'Zone could not be loaded [{self.time_zone}]: {e}') from e raise ValueError(f'Zone could not be loaded [{self.time_zone}]: {e}') from e

View File

@@ -22,6 +22,9 @@ def main():
print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}") print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}")
ts = TimestampStrings(ZoneInfo("Europe/Vienna")) ts = TimestampStrings(ZoneInfo("Europe/Vienna"))
print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}") print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}")
custom_tz = 'Europe/Paris'
ts = TimestampStrings(time_zone=custom_tz)
print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}")
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -3,7 +3,7 @@ PyTest: string_handling/timestamp_strings
""" """
from datetime import datetime from datetime import datetime
from unittest.mock import patch, MagicMock from unittest.mock import patch
from zoneinfo import ZoneInfo from zoneinfo import ZoneInfo
import pytest import pytest
@@ -119,18 +119,55 @@ class TestTimestampStrings:
assert ts2.time_zone == 'Europe/London' assert ts2.time_zone == 'Europe/London'
assert ts1.time_zone != ts2.time_zone assert ts1.time_zone != ts2.time_zone
@patch('corelibs.string_handling.timestamp_strings.ZoneInfo') def test_zoneinfo_called_correctly_with_string(self):
def test_zoneinfo_called_correctly(self, mock_zoneinfo: MagicMock): """Test that ZoneInfo is called with correct timezone when passing string"""
"""Test that ZoneInfo is called with correct timezone""" with patch('corelibs.string_handling.timestamp_strings.ZoneInfo') as mock_zoneinfo:
with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime:
mock_now = datetime(2023, 12, 25, 15, 30, 45)
mock_datetime.now.return_value = mock_now
custom_tz = 'Europe/Paris'
ts = TimestampStrings(time_zone=custom_tz)
assert ts.time_zone == custom_tz
mock_zoneinfo.assert_called_with(custom_tz)
def test_zoneinfo_object_parameter(self):
"""Test that ZoneInfo objects can be passed directly as timezone parameter"""
with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime: with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime:
mock_now = datetime(2023, 12, 25, 15, 30, 45) mock_now = datetime(2023, 12, 25, 15, 30, 45)
mock_datetime.now.return_value = mock_now mock_now_tz = datetime(2023, 12, 25, 15, 30, 45, tzinfo=ZoneInfo('Europe/Paris'))
mock_datetime.now.side_effect = [mock_now, mock_now_tz]
custom_tz = 'Europe/Paris' # Create a ZoneInfo object
ts = TimestampStrings(time_zone=custom_tz) custom_tz_obj = ZoneInfo('Europe/Paris')
assert ts.time_zone == custom_tz ts = TimestampStrings(time_zone=custom_tz_obj)
mock_zoneinfo.assert_called_with(custom_tz) # The time_zone should be the ZoneInfo object itself
assert ts.time_zone is custom_tz_obj
assert isinstance(ts.time_zone, ZoneInfo)
def test_zoneinfo_object_vs_string_equivalence(self):
"""Test that ZoneInfo object and string produce equivalent results"""
with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime:
mock_now = datetime(2023, 12, 25, 15, 30, 45)
mock_now_tz = datetime(2023, 12, 25, 15, 30, 45, tzinfo=ZoneInfo('Europe/Paris'))
mock_datetime.now.side_effect = [mock_now, mock_now_tz, mock_now, mock_now_tz]
# Test with string
ts_string = TimestampStrings(time_zone='Europe/Paris')
# Test with ZoneInfo object
ts_zoneinfo = TimestampStrings(time_zone=ZoneInfo('Europe/Paris'))
# Both should produce the same timestamp formats (though time_zone attributes will differ)
assert ts_string.today == ts_zoneinfo.today
assert ts_string.timestamp == ts_zoneinfo.timestamp
assert ts_string.timestamp_file == ts_zoneinfo.timestamp_file
# The time_zone attributes will be different types but represent the same timezone
assert str(ts_string.time_zone) == 'Europe/Paris'
assert isinstance(ts_zoneinfo.time_zone, ZoneInfo)
def test_edge_case_midnight(self): def test_edge_case_midnight(self):
"""Test timestamp formatting at midnight""" """Test timestamp formatting at midnight"""

2
uv.lock generated
View File

@@ -53,7 +53,7 @@ wheels = [
[[package]] [[package]]
name = "corelibs" name = "corelibs"
version = "0.24.1" version = "0.24.2"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "jmespath" }, { name = "jmespath" },