jaraco / tempora

MIT License
20 stars 7 forks source link

test failures because of removed timezones #25

Closed jcfp closed 12 months ago

jcfp commented 1 year ago

Apparently the Asia/Calcutta timezone got removed in some recent version of pytz, which causes the doctest in schedule.py to fail.

> __________________________ [doctest] tempora.schedule __________________________
> 001 
> 002 Classes for calling functions a schedule. Has time zone support.
> 003 
> 004 For example, to run a job at 08:00 every morning in 'Asia/Calcutta':
> 005 
> 006 >>> job = lambda: print("time is now", datetime.datetime())
> 007 >>> time = datetime.time(8, tzinfo=pytz.timezone('Asia/Calcutta'))
> UNEXPECTED EXCEPTION: UnknownTimeZoneError('Asia/Calcutta')
> Traceback (most recent call last):
>   File "/usr/lib/python3.11/doctest.py", line 1351, in __run
>     exec(compile(example.source, filename, "single",
>   File "<doctest tempora.schedule[1]>", line 1, in <module>
>   File "/usr/lib/python3/dist-packages/pytz/__init__.py", line 202, in timezone
>     raise UnknownTimeZoneError(zone)
> pytz.exceptions.UnknownTimeZoneError: 'Asia/Calcutta'

Similar failures occur in tests/test_schedule.py with US/Pacific and US/Eastern:

> __________________ TestTimezones.test_alternate_timezone_west __________________
> 
> self = <test_schedule.TestTimezones object at 0x7f67b0c612d0>
> 
>     def test_alternate_timezone_west(self):
> >       target_tz = pytz.timezone('US/Pacific')
> 
> tests/test_schedule.py:80: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> 
> zone = 'US/Pacific'
> 
>     def timezone(zone):
>         r''' Return a datetime.tzinfo implementation for the given timezone
>     
>         >>> from datetime import datetime, timedelta
>         >>> utc = timezone('UTC')
>         >>> eastern = timezone('US/Eastern')
>         >>> eastern.zone
>         'US/Eastern'
>         >>> timezone(unicode('US/Eastern')) is eastern
>         True
>         >>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
>         >>> loc_dt = utc_dt.astimezone(eastern)
>         >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
>         >>> loc_dt.strftime(fmt)
>         '2002-10-27 01:00:00 EST (-0500)'
>         >>> (loc_dt - timedelta(minutes=10)).strftime(fmt)
>         '2002-10-27 00:50:00 EST (-0500)'
>         >>> eastern.normalize(loc_dt - timedelta(minutes=10)).strftime(fmt)
>         '2002-10-27 01:50:00 EDT (-0400)'
>         >>> (loc_dt + timedelta(minutes=10)).strftime(fmt)
>         '2002-10-27 01:10:00 EST (-0500)'
>     
>         Raises UnknownTimeZoneError if passed an unknown zone.
>     
>         >>> try:
>         ...     timezone('Asia/Shangri-La')
>         ... except UnknownTimeZoneError:
>         ...     print('Unknown')
>         Unknown
>     
>         >>> try:
>         ...     timezone(unicode('\N{TRADE MARK SIGN}'))
>         ... except UnknownTimeZoneError:
>         ...     print('Unknown')
>         Unknown
>     
>         '''
>         if zone is None:
>             raise UnknownTimeZoneError(None)
>     
>         if zone.upper() == 'UTC':
>             return utc
>     
>         try:
>             zone = ascii(zone)
>         except UnicodeEncodeError:
>             # All valid timezones are ASCII
>             raise UnknownTimeZoneError(zone)
>     
>         zone = _case_insensitive_zone_lookup(_unmunge_zone(zone))
>         if zone not in _tzinfo_cache:
>             if zone in all_timezones_set:  # noqa
>                 fp = open_resource(zone)
>                 try:
>                     _tzinfo_cache[zone] = build_tzinfo(zone, fp)
>                 finally:
>                     fp.close()
>             else:
> >               raise UnknownTimeZoneError(zone)
> E               pytz.exceptions.UnknownTimeZoneError: 'US/Pacific'
> 
> /usr/lib/python3/dist-packages/pytz/__init__.py:202: UnknownTimeZoneError
> _____________________ TestTimezones.test_daylight_savings ______________________
> 
> self = <test_schedule.TestTimezones object at 0x7f67b0c620d0>
> 
>     def test_daylight_savings(self):
>         """
>         A command at 9am should always be 9am regardless of
>         a DST boundary.
>         """
>         with freezegun.freeze_time('2018-03-10 08:00:00'):
> >           target_tz = pytz.timezone('US/Eastern')
> 
> tests/test_schedule.py:97: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> 
> zone = 'US/Eastern'
> 
>     def timezone(zone):
>         r''' Return a datetime.tzinfo implementation for the given timezone
>     
>         >>> from datetime import datetime, timedelta
>         >>> utc = timezone('UTC')
>         >>> eastern = timezone('US/Eastern')
>         >>> eastern.zone
>         'US/Eastern'
>         >>> timezone(unicode('US/Eastern')) is eastern
>         True
>         >>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
>         >>> loc_dt = utc_dt.astimezone(eastern)
>         >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
>         >>> loc_dt.strftime(fmt)
>         '2002-10-27 01:00:00 EST (-0500)'
>         >>> (loc_dt - timedelta(minutes=10)).strftime(fmt)
>         '2002-10-27 00:50:00 EST (-0500)'
>         >>> eastern.normalize(loc_dt - timedelta(minutes=10)).strftime(fmt)
>         '2002-10-27 01:50:00 EDT (-0400)'
>         >>> (loc_dt + timedelta(minutes=10)).strftime(fmt)
>         '2002-10-27 01:10:00 EST (-0500)'
>     
>         Raises UnknownTimeZoneError if passed an unknown zone.
>     
>         >>> try:
>         ...     timezone('Asia/Shangri-La')
>         ... except UnknownTimeZoneError:
>         ...     print('Unknown')
>         Unknown
>     
>         >>> try:
>         ...     timezone(unicode('\N{TRADE MARK SIGN}'))
>         ... except UnknownTimeZoneError:
>         ...     print('Unknown')
>         Unknown
>     
>         '''
>         if zone is None:
>             raise UnknownTimeZoneError(None)
>     
>         if zone.upper() == 'UTC':
>             return utc
>     
>         try:
>             zone = ascii(zone)
>         except UnicodeEncodeError:
>             # All valid timezones are ASCII
>             raise UnknownTimeZoneError(zone)
>     
>         zone = _case_insensitive_zone_lookup(_unmunge_zone(zone))
>         if zone not in _tzinfo_cache:
>             if zone in all_timezones_set:  # noqa
>                 fp = open_resource(zone)
>                 try:
>                     _tzinfo_cache[zone] = build_tzinfo(zone, fp)
>                 finally:
>                     fp.close()
>             else:
> >               raise UnknownTimeZoneError(zone)
> E               pytz.exceptions.UnknownTimeZoneError: 'US/Eastern'
> 
> /usr/lib/python3/dist-packages/pytz/__init__.py:202: UnknownTimeZoneError

Old vs. New:

>>> pytz.__version__
'2022.1'
>>> [tz in pytz.all_timezones for tz in ('Asia/Calcutta', 'US/Pacific', 'US/Eastern')]
[True, True, True]

>>> pytz.__version__
'2023.3'
>>> [tz in pytz.all_timezones for tz in ('Asia/Calcutta', 'US/Pacific', 'US/Eastern')]
[False, False, False]
jaraco commented 12 months ago

This sounds like a bug with pytz, and when I run the tests, they now pick up 2023.3.post1 where the issue doesn't exist. I tried downgrading to 2023.03 and the issue also doesn't exist. I suspect the problem exists in your environment. If you can confirm that these timezones were in fact intentionally removed, then maybe there's something this project should do, but for now, it sound like there's nothing to be done here.

jcfp commented 12 months ago

Thanks for pointing me in the right direction, turns out it's a packaging change in debian and ubuntu that caused this (by dumping those older style timezones into a 'tzdata-legacy' package without warning).