Skip to content

Commit

Permalink
Introduce subdivisions aliases (#1662)
Browse files Browse the repository at this point in the history
Co-authored-by: ~Jhellico <[email protected]>
Co-authored-by: Arkadii Yakovets <[email protected]>
  • Loading branch information
3 people authored Feb 13, 2024
1 parent be26ebf commit 9f470d9
Show file tree
Hide file tree
Showing 20 changed files with 1,274 additions and 59 deletions.
13 changes: 8 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,10 @@ Available Countries

We currently support 143 country codes. The standard way to refer to a country
is by using its `ISO 3166-1 alpha-2 code`_, the same used for domain names, and
for a subdivision its `ISO 3166-2 code`_. Some of the countries support more
than one language for holiday names output.
for a subdivision its `ISO 3166-2 code`_. Some countries have common or foreign
names or abbreviations as aliases for their subdivisions. These are defined in
the (optional) ``subdivisions_aliases`` attribute.
Some of the countries support more than one language for holiday names output.
A default language is defined by ``default_language`` (optional) attribute
for each entity and is used as a fallback when neither user specified
language nor user locale language available. The default language code is
Expand All @@ -158,8 +160,9 @@ bank holidays, school holidays, additional (paid or non-paid) holidays, holidays
public employees, religious holidays (valid only for these religions followers). A list of all
categories supported by country is defined by ``supported_categories`` (optional) attribute.

The following is a list of supported countries, their subdivisions, available languages and
additional categories. All countries support **PUBLIC** holidays category by default.
The following is a list of supported countries, their subdivisions followed by their
aliases (if any) in brackets, available languages and additional holiday categories.
All countries support **PUBLIC** holidays category by default.
All other default values are highlighted with bold:


Expand Down Expand Up @@ -220,7 +223,7 @@ All other default values are highlighted with bold:
-
* - Austria
- AT
- States: 1, 2, 3, 4, 5, 6, 7, 8, **9**
- States: 1 (Burgenland, Bgld, B), 2 (Kärnten, Ktn, K), 3 (Niederösterreich, NÖ, N), 4 (Oberösterreich, OÖ, O), 5 (Salzburg, Sbg, S), 6 (Steiermark, Stmk, St), 7 (Tirol, T), 8 (Vorarlberg, Vbg, V), 9 (Wien, W)
- **de**, en_US, uk
- BANK
* - Azerbaijan
Expand Down
91 changes: 82 additions & 9 deletions holidays/countries/austria.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,48 @@ class Austria(HolidayBase, ChristianHolidays, InternationalHolidays):
default_language = "de"
supported_categories = (BANK, PUBLIC)
supported_languages = ("de", "en_US", "uk")
subdivisions = ("1", "2", "3", "4", "5", "6", "7", "8", "9")
subdivisions = (
"1", # Burgenland.
"2", # Kärnten.
"3", # Niederösterreich.
"4", # Oberösterreich.
"5", # Salzburg.
"6", # Steiermark.
"7", # Tirol.
"8", # Vorarlberg.
"9", # Wien.
)
subdivisions_aliases = {
"Burgenland": "1",
"Bgld": "1",
"B": "1",
"Kärnten": "2",
"Ktn": "2",
"K": "2",
"Niederösterreich": "3",
"NÖ": "3",
"N": "3",
"Oberösterreich": "4",
"OÖ": "4",
"O": "4",
"Salzburg": "5",
"Sbg": "5",
"S": "5",
"Steiermark": "6",
"Stmk": "6",
"St": "6",
"Tirol": "7",
"T": "7",
"Vorarlberg": "8",
"Vbg": "8",
"V": "8",
"Wien": "9",
"W": "9",
}

def __init__(self, *args, **kwargs) -> None:
ChristianHolidays.__init__(self)
InternationalHolidays.__init__(self)

# Set the default subdivision.
if not kwargs.get("subdiv", kwargs.get("state")):
kwargs["subdiv"] = "9"

super().__init__(*args, **kwargs)

def _populate_public_holidays(self):
Expand Down Expand Up @@ -58,11 +90,12 @@ def _populate_public_holidays(self):
# Assumption Day.
self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt"))

# National Day.
national_day = tr("Nationalfeiertag")
if 1919 <= self._year <= 1934:
# National Day.
self._add_holiday_nov_12(tr("Nationalfeiertag"))
self._add_holiday_nov_12(national_day)
if self._year >= 1967:
self._add_holiday_oct_26(tr("Nationalfeiertag"))
self._add_holiday_oct_26(national_day)

# All Saints' Day.
self._add_all_saints_day(tr("Allerheiligen"))
Expand All @@ -86,6 +119,46 @@ def _populate_bank_holidays(self):
# New Year's Eve.
self._add_new_years_eve(tr("Silvester"))

def _populate_subdiv_1_bank_holidays(self):
# St. Martin's Day.
self._add_holiday_nov_11(tr("Hl. Martin"))

def _populate_subdiv_2_bank_holidays(self):
# St. Joseph's Day.
self._add_saint_josephs_day(tr("Hl. Josef"))

# 1920 Carinthian plebiscite.
self._add_holiday_oct_10(tr("Tag der Volksabstimmung"))

def _populate_subdiv_3_bank_holidays(self):
# St. Leopold's Day.
self._add_holiday_nov_15(tr("Hl. Leopold"))

def _populate_subdiv_4_bank_holidays(self):
if self._year >= 2004:
# St. Florian's Day.
self._add_holiday_may_4(tr("Hl. Florian"))

def _populate_subdiv_5_bank_holidays(self):
# St. Rupert's Day.
self._add_holiday_sep_24(tr("Hl. Rupert"))

def _populate_subdiv_6_bank_holidays(self):
# St. Joseph's Day.
self._add_saint_josephs_day(tr("Hl. Josef"))

def _populate_subdiv_7_bank_holidays(self):
# St. Joseph's Day.
self._add_saint_josephs_day(tr("Hl. Josef"))

def _populate_subdiv_8_bank_holidays(self):
# St. Joseph's Day.
self._add_saint_josephs_day(tr("Hl. Josef"))

def _populate_subdiv_9_bank_holidays(self):
# St. Leopold's Day.
self._add_holiday_nov_15(tr("Hl. Leopold"))


class AT(Austria):
pass
Expand Down
46 changes: 32 additions & 14 deletions holidays/holiday_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ def _populate(self, year):
"""The market's ISO 3166-1 alpha-2 code."""
subdivisions: Tuple[str, ...] = ()
"""The subdivisions supported for this country (see documentation)."""
subdivisions_aliases: Dict[str, str] = {}
"""Aliases for the ISO 3166-2 subdivision codes with the key as alias and
the value the ISO 3166-2 subdivision code."""
years: Set[int]
"""The years calculated."""
expand: bool
Expand All @@ -217,7 +220,7 @@ def _populate(self, year):
observed: bool
"""Whether dates when public holiday are observed are included."""
subdiv: Optional[str] = None
"""The subdiv requested."""
"""The subdiv requested as ISO 3166-2 code or one of the aliases."""
special_holidays: Dict[int, Union[SpecialHoliday, SubstitutedHoliday]] = {}
"""A list of the country-wide special (as opposite to regular) holidays for
a specific year."""
Expand Down Expand Up @@ -262,8 +265,8 @@ def __init__(
following Monday). This doesn't work for all countries.
:param subdiv:
The subdivision (e.g. state or province); not implemented for all
countries (see documentation).
The subdivision (e.g. state or province) as a ISO 3166-2 code
or its alias; not implemented for all countries (see documentation).
:param prov:
*deprecated* use subdiv instead.
Expand Down Expand Up @@ -304,10 +307,10 @@ def __init__(
if isinstance(subdiv, int):
subdiv = str(subdiv)

subdivisions_aliases = tuple(sorted(self.subdivisions_aliases))
# Unsupported subdivisions.
if (
not isinstance(self, HolidaySum)
and subdiv not in self.subdivisions + self._deprecated_subdivisions
if not isinstance(self, HolidaySum) and subdiv not in (
self.subdivisions + subdivisions_aliases + self._deprecated_subdivisions
):
raise NotImplementedError(
f"Entity `{self._entity_code}` does not have subdivision {subdiv}"
Expand All @@ -326,7 +329,9 @@ def __init__(
warnings.warn(
"This subdivision is deprecated and will be removed after "
"Dec, 1 2023. The list of supported subdivisions: "
f"{', '.join(sorted(self.subdivisions))}.",
f"{', '.join(sorted(self.subdivisions))}; "
"the list of supported subdivisions aliases: "
f"{', '.join(subdivisions_aliases)}.",
DeprecationWarning,
)

Expand Down Expand Up @@ -657,19 +662,32 @@ def _entity_code(self):

@cached_property
def _normalized_subdiv(self):
return self.subdiv.translate(
str.maketrans(
{
"-": "_",
" ": "_",
}
return (
self.subdivisions_aliases.get(self.subdiv, self.subdiv)
.translate(
str.maketrans(
{
"-": "_",
" ": "_",
}
)
)
).lower()
.lower()
)

@cached_property
def _sorted_categories(self):
return sorted(self.categories)

@classmethod
def get_subdivision_aliases(cls) -> Dict[str, List]:
"""Get subdivision aliases."""
subdivision_aliases: Dict[str, List[str]] = {s: [] for s in cls.subdivisions}
for alias, subdivision in cls.subdivisions_aliases.items():
subdivision_aliases[subdivision].append(alias)

return subdivision_aliases

def _is_leap_year(self) -> bool:
"""
Returns True if the year is leap. Returns False otherwise.
Expand Down
26 changes: 25 additions & 1 deletion holidays/locale/de/LC_MESSAGES/AT.po
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Authors: ~Jhellico <[email protected]>, (c) 2023.
msgid ""
msgstr ""
"Project-Id-Version: Python Holidays 0.28\n"
"Project-Id-Version: Python Holidays 0.42\n"
"POT-Creation-Date: 2023-04-01 17:13+0300\n"
"PO-Revision-Date: 2023-04-01 17:15+0300\n"
"Last-Translator: ~Jhellico <[email protected]>\n"
Expand Down Expand Up @@ -78,3 +78,27 @@ msgstr ""
#. New Year's Eve.
msgid "Silvester"
msgstr ""

#. St. Martin's Day.
msgid "Hl. Martin"
msgstr ""

#. St. Joseph's Day.
msgid "Hl. Josef"
msgstr ""

#. 1920 Carinthian plebiscite.
msgid "Tag der Volksabstimmung"
msgstr ""

#. St. Leopold's Day.
msgid "Hl. Leopold"
msgstr ""

#. St. Florian's Day.
msgid "Hl. Florian"
msgstr ""

#. St. Rupert's Day.
msgid "Hl. Rupert"
msgstr ""
26 changes: 25 additions & 1 deletion holidays/locale/en_US/LC_MESSAGES/AT.po
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
msgid ""
msgstr ""
"Project-Id-Version: Python Holidays 0.28\n"
"Project-Id-Version: Python Holidays 0.42\n"
"POT-Creation-Date: 2023-04-01 17:13+0300\n"
"PO-Revision-Date: 2023-04-01 17:18+0300\n"
"Last-Translator: ~Jhellico <[email protected]>\n"
Expand Down Expand Up @@ -79,3 +79,27 @@ msgstr "Christmas Eve"
#. New Year's Eve.
msgid "Silvester"
msgstr "New Year's Eve"

#. St. Martin's Day.
msgid "Hl. Martin"
msgstr "St. Martin's Day"

#. St. Joseph's Day.
msgid "Hl. Josef"
msgstr "St. Joseph's Day"

#. 1920 Carinthian plebiscite.
msgid "Tag der Volksabstimmung"
msgstr "1920 Carinthian plebiscite"

#. St. Leopold's Day.
msgid "Hl. Leopold"
msgstr "St. Leopold's Day"

#. St. Florian's Day.
msgid "Hl. Florian"
msgstr "St. Florian's Day"

#. St. Rupert's Day.
msgid "Hl. Rupert"
msgstr "St. Rupert's Day"
26 changes: 25 additions & 1 deletion holidays/locale/uk/LC_MESSAGES/AT.po
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
msgid ""
msgstr ""
"Project-Id-Version: Python Holidays 0.28\n"
"Project-Id-Version: Python Holidays 0.42\n"
"POT-Creation-Date: 2023-04-01 17:13+0300\n"
"PO-Revision-Date: 2023-04-01 17:27+0300\n"
"Last-Translator: ~Jhellico <[email protected]>\n"
Expand Down Expand Up @@ -79,3 +79,27 @@ msgstr "Святий вечір"
#. New Year's Eve.
msgid "Silvester"
msgstr "Переддень Нового року"

#. St. Martin's Day.
msgid "Hl. Martin"
msgstr "День Святого Мартина"

#. St. Joseph's Day.
msgid "Hl. Josef"
msgstr "День Святого Йосипа"

#. 1920 Carinthian plebiscite.
msgid "Tag der Volksabstimmung"
msgstr "Річниця референдуму 1920 року в Карінтії"

#. St. Leopold's Day.
msgid "Hl. Leopold"
msgstr "День Святого Леопольда"

#. St. Florian's Day.
msgid "Hl. Florian"
msgstr "День Святого Флоріана"

#. St. Rupert's Day.
msgid "Hl. Rupert"
msgstr "День Святого Руперта"
4 changes: 2 additions & 2 deletions holidays/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ def country_holidays(
An ISO 3166-1 Alpha-2 country code.
:param subdiv:
The subdivision (e.g. state or province); not implemented for all
countries (see documentation).
The subdivision (e.g. state or province) as a ISO 3166-2 code
or its alias; not implemented for all countries (see documentation).
:param years:
The year(s) to pre-calculate public holidays for at instantiation.
Expand Down
Loading

0 comments on commit 9f470d9

Please sign in to comment.