Compare commits

..

4 Commits

Author SHA1 Message Date
Clemens Schwaighofer
2690a285d9 v0.24.3: Pytest fixes 2025-09-25 15:38:29 +09:00
Clemens Schwaighofer
bb60a570d0 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
2025-09-25 15:36:47 +09:00
Clemens Schwaighofer
ca0ab2d7d1 v0.24.2: TimestampString allows ZoneInfo object as zone name 2025-09-25 15:16:19 +09:00
Clemens Schwaighofer
38bae7fb46 TimestampStrings allows ZoneInfo object as time_zone parameter
So we can use pre-parsed data

Some tests for parsing settings, timestamp output
2025-09-25 15:14:40 +09:00
6 changed files with 63 additions and 13 deletions

View File

@@ -1,7 +1,7 @@
# MARK: Project info # MARK: Project info
[project] [project]
name = "corelibs" name = "corelibs"
version = "0.24.1" version = "0.24.3"
description = "Collection of utils for Python scripts" description = "Collection of utils for Python scripts"
readme = "README.md" readme = "README.md"
requires-python = ">=3.13" requires-python = ">=3.13"

View File

@@ -23,11 +23,13 @@ class TimestampStrings:
TIME_ZONE: str = 'Asia/Tokyo' TIME_ZONE: str = 'Asia/Tokyo'
def __init__(self, time_zone: str | None = None): def __init__(self, time_zone: str | ZoneInfo | None = None):
self.timestamp_now = datetime.now() self.timestamp_now = datetime.now()
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(ZoneInfo(self.time_zone)) self.timestamp_now_tz = datetime.now(
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
self.today = self.timestamp_now.strftime('%Y-%m-%d') self.today = self.timestamp_now.strftime('%Y-%m-%d')

View File

@@ -24,6 +24,7 @@ match_source_list=foo,bar
element_a=Static energy element_a=Static energy
element_b=123.5 element_b=123.5
element_c=True element_c=True
elemend_d=AB:CD;EF
email=foo@bar.com,other+bar-fee@domain-com.cp, email=foo@bar.com,other+bar-fee@domain-com.cp,
email_not_mandatory= email_not_mandatory=
email_bad=gii@bar.com email_bad=gii@bar.com

View File

@@ -4,10 +4,12 @@
Test for double byte format Test for double byte format
""" """
from zoneinfo import ZoneInfo
from corelibs.string_handling.timestamp_strings import TimestampStrings from corelibs.string_handling.timestamp_strings import TimestampStrings
def main(): def main():
"""test"""
ts = TimestampStrings() ts = TimestampStrings()
print(f"TS: {ts.timestamp_now}") print(f"TS: {ts.timestamp_now}")
@@ -16,6 +18,14 @@ def main():
except ValueError as e: except ValueError as e:
print(f"Value error: {e}") print(f"Value error: {e}")
ts = TimestampStrings("Europe/Vienna")
print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}")
ts = TimestampStrings(ZoneInfo("Europe/Vienna"))
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__":
main() 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.23.0" version = "0.24.2"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "jmespath" }, { name = "jmespath" },