11from dataclasses import dataclass
2- from typing import Callable , Dict , Iterator , List , Union
2+ from typing import Callable , Dict , Iterator , List , Literal , Union
33
44import dateutil
55from arrow import Arrow
@@ -19,7 +19,7 @@ class Holiday:
1919 flags : str = ""
2020 notes : str = ""
2121
22- def as_dict (self ) -> dict :
22+ def as_dict (self ) -> Dict [ str , str ] :
2323 return {
2424 "locale" : self .locale ,
2525 "region" : self .region ,
@@ -31,26 +31,30 @@ def as_dict(self) -> dict:
3131
3232
3333class HolidayGenerator :
34- def __init__ (self , country_id : str , default_lang : str ) :
34+ def __init__ (self , country_id : str , default_lang : Union [ str , None ]) -> None :
3535 self .name_dict : Dict [str , str ] = {}
3636 self .notes : str = ""
3737 self .regions : List [str ] = ["" ]
3838 self .flags : str = ""
3939 self .date : Callable [[int ], Union [Arrow , None ]] = lambda year : None
4040 self .country_id : str = country_id
41- self .default_lang : str = default_lang
41+ self .default_lang : Union [ str , None ] = default_lang
4242 self .filters : List [Callable [[int ], bool ]] = []
4343
44- def with_name (self , name : str , lang : str = None ) -> 'HolidayGenerator' :
44+ def with_name (self , name : str , lang : Union [ str , None ] = None ) -> 'HolidayGenerator' :
4545 lang = self .default_lang if lang is None else lang
46+
47+ if lang is None :
48+ raise ValueError ("No language specified and no default language was provided!" )
49+
4650 self .name_dict [lang ] = name
4751 return self
4852
4953 def with_names (self , name_dict : Dict [str , str ]) -> 'HolidayGenerator' :
5054 self .name_dict = name_dict
5155 return self
5256
53- def on (self , date_func : Callable [[int ], Arrow ] = None ) -> 'HolidayGenerator' :
57+ def on (self , date_func : Callable [[int ], Union [ Arrow , None ]] ) -> 'HolidayGenerator' :
5458 self .date = date_func
5559 return self
5660
@@ -128,27 +132,28 @@ class Country(metaclass=PluginMount):
128132 id : str
129133 languages : List [str ]
130134 default_lang : Union [str , None ] = None
131- easter_type : int
132- holiday_generators : list
133- regions : list
135+ easter_type : Literal [ 1 , 2 , 3 ]
136+ holiday_generators : List [ HolidayGenerator ]
137+ regions : List [ 'Region' ]
134138
135- def __init__ (self ):
139+ def __init__ (self ) -> None :
136140 if not self .id :
137141 raise ValueError (f"Country '{ self .__class__ .__name__ } ' does not provide an id!" )
138142 if not self .languages :
139143 raise ValueError (f"Country '{ self .__class__ .__name__ } ' does not list any languages!" )
140144 if self .default_lang is not None and self .default_lang not in self .languages :
141145 raise ValueError (f"Country '{ self .__class__ .__name__ } ' does not list language '{ self .default_lang } '!" )
142146
143- self .default_lang = self .languages [0 ] if self .default_lang is None and len (self .languages ) == 1 else self .default_lang
147+ self .default_lang = self .languages [0 ] if self .default_lang is None and len (
148+ self .languages ) == 1 else self .default_lang
144149 self .holiday_generators = []
145150 self .regions = []
146151
147152 @staticmethod
148- def get (identifier ) :
153+ def get (identifier : str ) -> Union [ Callable [[], 'Country' ], None ] :
149154 return Country .get_plugin (identifier , "id" )
150155
151- def validate_language_or_get_default (self , lang_id : str ) -> str :
156+ def validate_language_or_get_default (self , lang_id : Union [ str , None ] ) -> str :
152157 if lang_id and lang_id .lower () not in self .languages :
153158 raise ValueError (
154159 f"Language '{ lang_id } ' is not defined for country '{ self .id } '! Choose one of [{ ', ' .join (self .languages )} ]." )
@@ -182,7 +187,7 @@ def wrapper(year: int) -> Arrow:
182187
183188
184189class Region :
185- def __init__ (self , id : str , country : Country ):
190+ def __init__ (self , id : str , country : Country ) -> None :
186191 self .id : str = id
187192 self .country : Country = country
188193 self .holiday_generators : List [HolidayGenerator ] = []
0 commit comments