from typing import List, Optional from .dates_bank_holidays_data import BANK_HOLIDAYS from .dates_bank_holidays_types import BankHoliday, UkRegion def bank_holidays(region: UkRegion, year: int) -> List[BankHoliday]: """The bank holidays for a UK region and year, in date order, as gov.uk publishes them. A year the data does not cover is an error rather than an empty list, because an empty list reads as "no holidays" and a deadline calculation would then count Christmas Day as a working day. """ if isinstance(year, bool) or not isinstance(year, int): raise TypeError("year must be an integer, received %r" % (year,)) first: Optional[int] = None last: Optional[int] = None found: List[BankHoliday] = [] prefix = "%04d-" % (year,) for row in BANK_HOLIDAYS: if row.region != region: continue row_year = int(row.date[0:4]) if first is None or row_year < first: first = row_year if last is None or row_year > last: last = row_year if row.date.startswith(prefix): found.append(BankHoliday(date=row.date, title=row.title, substitute=row.substitute)) if first is None or last is None: raise ValueError( 'unknown region "%s": expected england-and-wales, scotland or northern-ireland' % (region,) ) if year < first or year > last: raise ValueError( "no bank holiday data for %s in %s: the published calendar covers %s to %s" % (region, year, first, last) ) # ISO dates sort correctly as strings. return sorted(found, key=lambda holiday: holiday.date)