import re
from collections import OrderedDict, namedtuple
from email.errors import HeaderParseError
+from typing import Tuple, Optional, List, Any, Callable, Union, TypeVar, Dict
import mwparserfromhell # https://github.com/earwig/mwparserfromhell
from wrpylib.mwmarkup import format_template_table
+T = TypeVar("T") # use for generic type annotations
+E = TypeVar("E") # use for generic type annotations
+N = TypeVar("N") # use for generic type annotations
+
+
# FromToConverter type
# --------------------
# optional converter
# ------------------
-def opt_from_str(value, from_str, empty=None):
+def opt_from_str(value: str, from_str: Callable[[str], T], empty: E = None) -> Union[T, E]:
"""Makes the converter `from_str` "optional"
by replacing the empty string with a predefined value (default: None)."""
return empty if value == '' else from_str(value)
-def opt_to_str(value, to_str, empty=None):
+def opt_to_str(value: Union[T, E], to_str: Callable[[T], str], empty: E = None) -> str:
return '' if value == empty else to_str(value)
# "no" converter
# --------------
-def no_german_from_str(value, from_str, use_tuple=True, no_value=None):
+def no_german_from_str(value: str, from_str: Callable[[str], T], use_tuple: bool = True, no_value: N = None) \
+ -> Union[Tuple[bool, Union[T, N]], T, N]:
"""Makes it possible to have "Nein" as special value. If use_tuple is True, a tuple is returned. The first
- entry of the tuple is False in case the value is "Nein", otherwiese the first value is True. The second value is
+ entry of the tuple is False in case the value is "Nein", otherwise the first value is True. The second value is
no_value in case of the value being "Nein", otherwise it is the result of from_str(value).
If use_tuple is False, no_value is returned in case the value is "Nein", otherwise the result of from_str(value)."""
if value == 'Nein':
return (True, from_str(value)) if use_tuple else from_str(value)
-def no_german_to_str(value, to_str, use_tuple=True, no_value=None):
+def no_german_to_str(value: Union[Tuple[bool, Union[T, N]], T, N], to_str: Callable[[T], str], use_tuple: bool = True,
+ no_value: N = None) -> str:
if use_tuple:
if not value[0]:
return 'Nein'
# "optional"/"no" converter
# -------------------------
-def opt_no_german_from_str(value, from_str, use_tuple=True, no_value=None, empty=(None, None)):
+def opt_no_german_from_str(value: str, from_str: Callable[[str], T], use_tuple: bool = True, no_value: N = None,
+ empty: E = (None, None)) -> Union[Tuple[bool, Union[T, N]], T, N, E]:
+ """
+ 'abc' -> (True, from_str('abc')) or from_str('abc')
+ 'Nein' -> (False, no_value) or no_value
+ '' -> empty
+ """
return opt_from_str(value, lambda v: no_german_from_str(v, from_str, use_tuple, no_value), empty)
-def opt_no_german_to_str(value, to_str, use_tuple=True, no_value=None, empty=(None, None)):
+def opt_no_german_to_str(value: Union[Tuple[bool, Union[T, N]], T, N, E], to_str: Callable[[T], str], use_tuple=True,
+ no_value: N = None, empty: E = (None, None)) -> str:
+ """
+ (True, 'abc') -> to_value('abc')
+ (False, no_value) -> 'Nein'
+ empty -> ''
+ """
return opt_to_str(value, lambda v: no_german_to_str(v, to_str, use_tuple, no_value), empty)
def choice_from_str(value, choices):
"""Returns the value if it is a member of the choices iterable."""
if value not in choices:
- raise ValueError('{} is an invalid value')
+ raise ValueError(f"'{value}' is an invalid value")
return value
# dictkey converter
# -----------------
-def dictkey_from_str(value, key_str_dict):
+def dictkey_from_str(value: str, key_str_dict: Dict[T, str]) -> T:
"""Returns the key of an entry in the key_str_dict if the value of the entry corresponds to the given value."""
try:
return dict(list(zip(key_str_dict.values(), key_str_dict.keys())))[value]
except KeyError:
- raise ValueError("Invalid value '{}'".format(value))
+ raise ValueError(f"Invalid value '{value}'")
-def dictkey_to_str(value, key_str_dict):
+def dictkey_to_str(value: T, key_str_dict: Dict[T, str]) -> str:
try:
return key_str_dict[value]
except KeyError:
- raise ValueError("Invalid value '{}'".format(value))
+ raise ValueError(f"Invalid value '{value}'")
# enum/"list" converter
# ---------------------
-def enum_from_str(value, from_str, separator=';', min_len=0):
+def enum_from_str(value: str, from_str: Callable[[str], T], separator: str = ';', min_len: int = 0) -> List[T]:
"""Semicolon separated list of entries with the same "type"."""
values = value.split(separator)
if len(values) == 1 and values[0] == '':
values = []
if len(values) < min_len:
- raise ValueError('at least {} entry/entries have to be in the enumeration'.format(min_len))
+ raise ValueError(f'at least {min_len} entry/entries have to be in the enumeration')
return list(map(from_str, map(str.strip, values)))
-def enum_to_str(value, to_str, separator='; '):
+def enum_to_str(value: List[T], to_str: Callable[[T], str], separator='; ') -> str:
return separator.join(map(to_str, value))
# value/comment converter
# -----------------------
-def value_comment_from_str(value, value_from_str, comment_from_str, comment_optional=False):
+def value_comment_from_str(value: str, value_from_str: Callable[[str], T], comment_from_str: Callable[[str], E],
+ comment_optional: bool = False) -> Tuple[T, E]:
"""Makes it possible to have a mandatory comment in parenthesis at the end of the string."""
comment = ''
if value.endswith(')'):
raise ValueError('mandatory comment not found')
else:
if not comment_optional:
- raise ValueError('mandatory comment not found in "{}"'.format(value))
+ raise ValueError(f'mandatory comment not found in "{value}"')
return value_from_str(value), comment_from_str(comment)
-def value_comment_to_str(value, value_to_str, comment_to_str, comment_optional=False):
+def value_comment_to_str(value: Tuple[T, E], value_to_str: Callable[[T], str], comment_to_str: Callable[[E], str],
+ comment_optional: bool = False) -> str:
left = value_to_str(value[0])
comment = comment_to_str(value[1])
if len(comment) > 0 or not comment_optional:
- comment = '({})'.format(comment)
+ comment = f'({comment})'
if len(left) == 0:
return comment
if len(comment) == 0:
return left
- return '{} {}'.format(left, comment)
+ return f'{left} {comment}'
# string converter
# ----------------
-def str_from_str(value):
+def str_from_str(value: str) -> str:
"""Converter that takes any string and returns it as string without validation.
In other words, this function does nothing and just returns its argument."""
return value
-def str_to_str(value):
+def str_to_str(value: str) -> str:
return value
-def req_str_from_str(value):
+def req_str_from_str(value: str) -> str:
if value == '':
raise ValueError('missing required value')
return str_from_str(value)
-def opt_str_from_str(value):
+def opt_str_from_str(value: str) -> Optional[str]:
return opt_from_str(value, str_from_str)
-def opt_str_to_str(value):
+def opt_str_to_str(value: Optional[str]) -> str:
return opt_to_str(value, str_to_str)
# optional no or string converter
# -------------------------------
-def opt_no_or_str_from_str(value):
+def opt_no_or_str_from_str(value: str) -> Tuple[Optional[bool], Optional[str]]:
"""
'Nein' => (False, None); 'Nur Wochenende' => (True, 'Nur Wochenende'); 'Ja' => (True, 'Ja'); '' => (None, None)"""
return opt_no_german_from_str(value, req_str_from_str)
-def opt_no_or_str_to_str(value):
+def opt_no_or_str_to_str(value: Tuple[Optional[bool], Optional[str]]) -> str:
return opt_no_german_to_str(value, str_to_str)
# integer converter
# -----------------
-def int_from_str(value, min=None, max=None):
+def int_from_str(value: str, minimum: Optional[int] = None, maximum: Optional[int] = None) -> int:
"""Converter that takes a string representation of an integer and returns the integer.
:param value: string representation of an integer
- :param min: If not None, the integer has to be at least min
- :param max: If not None, the integer has to be no more than max
+ :param minimum: If not None, the integer has to be at least min
+ :param maximum: If not None, the integer has to be no more than max
"""
value = int(value)
- if min is not None and value < min:
- raise ValueError('{} must be >= than {}'.format(value, min))
- if max is not None and value > max:
- raise ValueError('{} must be <= than {}'.format(value, max))
+ if minimum is not None and value < minimum:
+ raise ValueError(f'{value} must be >= than {minimum}')
+ if maximum is not None and value > maximum:
+ raise ValueError(f'{value} must be <= than {maximum}')
return value
-def int_to_str(value):
+def int_to_str(value: int) -> str:
return str(value)
-def opt_int_from_str(value, min=None, max=None):
- return opt_from_str(value, lambda val: int_from_str(val, min, max))
+def opt_int_from_str(value: str, minimum: Optional[int] = None, maximum: Optional[int] = None) -> Optional[int]:
+ return opt_from_str(value, lambda val: int_from_str(val, minimum, maximum))
-def opt_int_to_str(value):
+def opt_int_to_str(value: Optional[int]) -> str:
return opt_to_str(value, int_to_str)
-def opt_uint_from_str(value, min=0, max=None):
+def opt_uint_from_str(value: str, minimum: int = 0, maximum: Optional[int] = None) -> Optional[int]:
"""Optional positive integer."""
- return opt_int_from_str(value, min, max)
+ return opt_int_from_str(value, minimum, maximum)
-def opt_uint_to_str(value):
+def opt_uint_to_str(value: Optional[int]) -> str:
return opt_int_to_str(value)
BOOL_GERMAN = OrderedDict([(False, 'Nein'), (True, 'Ja')])
-def bool_german_from_str(value):
+def bool_german_from_str(value: str) -> bool:
return dictkey_from_str(value, BOOL_GERMAN)
-def bool_german_to_str(value):
+def bool_german_to_str(value: bool) -> str:
return dictkey_to_str(value, BOOL_GERMAN)
-def opt_bool_german_from_str(value):
+def opt_bool_german_from_str(value: str) -> Optional[bool]:
return opt_from_str(value, bool_german_from_str)
-def opt_bool_german_to_str(value):
+def opt_bool_german_to_str(value: Optional[bool]) -> str:
return opt_to_str(value, bool_german_to_str)
TRISTATE_GERMAN = OrderedDict([(0.0, 'Nein'), (0.5, 'Teilweise'), (1.0, 'Ja')])
-def tristate_german_from_str(value):
+def tristate_german_from_str(value: str) -> float:
return dictkey_from_str(value, TRISTATE_GERMAN)
-def tristate_german_to_str(value):
+def tristate_german_to_str(value: float) -> str:
return dictkey_to_str(value, TRISTATE_GERMAN)
-def opt_tristate_german_from_str(value):
+def opt_tristate_german_from_str(value: str) -> Optional[float]:
return opt_from_str(value, tristate_german_from_str)
-def opt_tristate_german_to_str(value):
+def opt_tristate_german_to_str(value: Optional[float]) -> str:
return opt_to_str(value, tristate_german_to_str)
# tristate with comment converter
# -------------------------------
-def opt_tristate_german_comment_from_str(value):
+def opt_tristate_german_comment_from_str(value: str) -> Tuple[Optional[float], Optional[str]]:
"""Ja, Nein or Teilweise, optionally with comment in parenthesis."""
return value_comment_from_str(value, opt_tristate_german_from_str, opt_str_from_str, True)
-def opt_tristate_german_comment_to_str(value):
+def opt_tristate_german_comment_to_str(value: Tuple[Optional[float], Optional[str]]) -> str:
return value_comment_to_str(value, opt_tristate_german_to_str, opt_str_to_str, True)
-opt_tristate_german_comment_converter = FromToConverter(opt_tristate_german_comment_from_str, opt_tristate_german_comment_to_str)
+opt_tristate_german_comment_converter = FromToConverter(opt_tristate_german_comment_from_str,
+ opt_tristate_german_comment_to_str)
# url converter
# -------------
-def url_from_str(value):
+def url_from_str(value: str) -> str:
result = urllib.parse.urlparse(value)
if result.scheme not in ['http', 'https']:
raise ValueError('scheme has to be http or https')
return value
-def url_to_str(value):
+def url_to_str(value: str) -> str:
return value
# webauskunft converter
# ---------------------
-def webauskunft_from_str(value):
+def webauskunft_from_str(value: str) -> Tuple[Optional[bool], Optional[str]]:
"""Converts a URL or 'Nein' to a tuple
'http://www.example.com/' -> (True, 'http://www.example.com/')
'Nein' -> (False, None)
return opt_no_german_from_str(value, url_from_str)
-def webauskunft_to_str(value):
+def webauskunft_to_str(value: Tuple[Optional[bool], Optional[str]]) -> str:
return opt_no_german_to_str(value, url_to_str)
# wikipage converter
# ------------------
-def wikipage_from_str(value):
+def wikipage_from_str(value: str) -> str:
"""Validates wiki page name like '[[Birgitzer Alm]]'.
The page is not checked for existence.
An empty string is an error.
return value
-def wikipage_to_str(value):
+def wikipage_to_str(value: str) -> str:
return value
-def opt_wikipage_enum_from_str(value):
+def opt_wikipage_enum_from_str(value: str) -> Optional[List[str]]:
"""Validates a list of wiki pages like '[[Birgitzer Alm]]; [[Kemater Alm]]'.
'[[Birgitzer Alm]]; [[Kemater Alm]]' => ['[[Birgitzer Alm]]', '[[Kemater Alm]]']
'[[Birgitzer Alm]]' => ['[[Birgitzer Alm]]']
return opt_no_german_from_str(value, lambda val: enum_from_str(val, wikipage_from_str), False, [], None)
-def opt_wikipage_enum_to_str(value):
+def opt_wikipage_enum_to_str(value: Optional[List[str]]) -> str:
return opt_no_german_to_str(value, lambda val: enum_to_str(val, wikipage_to_str), False, [], None)
# email converter
# ---------------
-def email_from_str(value):
+def email_from_str(value: str) -> str:
"""Takes an email address like 'office@example.com', checks it for correctness and returns it again as string."""
try:
email.headerregistry.Address(addr_spec=value)
return value
-def email_to_str(value):
+def email_to_str(value: str) -> str:
return str(value)
-def masked_email_from_str(value, mask='(at)', masked_only=False):
+def masked_email_from_str(value: str, mask='(at)', masked_only=False) -> Tuple[str, bool]:
"""Converts an email address that is possibly masked. Returns a tuple. The first parameter is the un-masked
email address as string, the second is a boolean telling whether the address was masked."""
unmasked = value.replace(mask, '@')
return email_from_str(unmasked), was_masked
-def masked_email_to_str(value, mask='(at)'):
+def masked_email_to_str(value: Tuple[str, bool], mask='(at)') -> str:
"""Value is a tuple. The first entry is the email address, the second one is a boolean telling whether the
email address should be masked."""
email, do_masking = value
return email
-def emails_from_str(value):
- return opt_no_german_from_str(value, lambda val: enum_from_str(val, lambda v: value_comment_from_str(v, masked_email_from_str, opt_str_from_str, True)), False, [], None)
+def emails_from_str(value: str) -> Optional[List[Tuple[str, str]]]:
+ return opt_no_german_from_str(
+ value,
+ lambda val:
+ enum_from_str(val, lambda v: value_comment_from_str(v, masked_email_from_str, opt_str_from_str, True)),
+ False, [], None)
-def emails_to_str(value):
- return opt_no_german_to_str(value, lambda val: enum_to_str(val, lambda v: value_comment_to_str(v, masked_email_to_str, opt_str_to_str, True)), False, [], None)
+def emails_to_str(value: Optional[List[Tuple[str, str]]]) -> str:
+ return opt_no_german_to_str(
+ value,
+ lambda val: enum_to_str(val, lambda v: value_comment_to_str(v, masked_email_to_str, opt_str_to_str, True)),
+ False, [], None)
emails_converter = FromToConverter(emails_from_str, emails_to_str)
# phone converter
# ---------------
-def phone_number_from_str(value):
+def phone_number_from_str(value: str) -> str:
match = re.match(r'\+\d+(-\d+)*$', value)
if match is None:
raise ValueError('invalid format of phone number - use something like +43-699-1234567')
return value
-def phone_number_to_str(value):
+def phone_number_to_str(value: str) -> str:
return value
-def opt_phone_comment_enum_from_str(value, comment_optional=False):
- return opt_no_german_from_str(value, lambda val: enum_from_str(val, lambda v: value_comment_from_str(v, phone_number_from_str, opt_str_from_str if comment_optional else req_str_from_str, comment_optional)), False, [], None)
+def opt_phone_comment_enum_from_str(value: str, comment_optional: bool = False) -> Optional[List[Tuple[str, str]]]:
+ return opt_no_german_from_str(
+ value,
+ lambda val: enum_from_str(
+ val,
+ lambda v:
+ value_comment_from_str(
+ v,
+ phone_number_from_str,
+ opt_str_from_str if comment_optional else req_str_from_str,
+ comment_optional
+ )
+ ), False, [], None)
-def opt_phone_comment_enum_to_str(value, comment_optional=False):
- return opt_no_german_to_str(value, lambda val: enum_to_str(val, lambda v: value_comment_to_str(v, phone_number_to_str, opt_str_to_str if comment_optional else str_to_str, comment_optional)), False, [], None)
+def opt_phone_comment_enum_to_str(value: Optional[List[Tuple[str, str]]], comment_optional: bool = False) -> str:
+ return opt_no_german_to_str(
+ value,
+ lambda val: enum_to_str(
+ val, lambda v: value_comment_to_str(
+ v, phone_number_to_str, opt_str_to_str if comment_optional else str_to_str, comment_optional)),
+ False, [], None)
opt_phone_comment_enum_converter = FromToConverter(opt_phone_comment_enum_from_str, opt_phone_comment_enum_to_str)
-opt_phone_comment_opt_enum_converter = FromToConverter(lambda value: opt_phone_comment_enum_from_str(value, True), lambda value: opt_phone_comment_enum_to_str(value, True))
+opt_phone_comment_opt_enum_converter = FromToConverter(lambda value: opt_phone_comment_enum_from_str(value, True),
+ lambda value: opt_phone_comment_enum_to_str(value, True))
# longitude/latitude converter
return '{:.6f} N {:.6f} E'.format(value.lat, value.lon)
-def opt_lonlat_from_str(value):
+def opt_lonlat_from_str(value: str) -> LonLat:
return opt_from_str(value, lonlat_from_str, lonlat_none)
-def opt_lonlat_to_str(value):
+def opt_lonlat_to_str(value: LonLat) -> str:
return opt_to_str(value, lonlat_to_str, lonlat_none)
DIFFICULTY_GERMAN = OrderedDict([(1, 'leicht'), (2, 'mittel'), (3, 'schwer')])
-def difficulty_german_from_str(value):
+def difficulty_german_from_str(value: str) -> int:
return dictkey_from_str(value, DIFFICULTY_GERMAN)
-def difficulty_german_to_str(value):
+def difficulty_german_to_str(value: int) -> str:
return dictkey_to_str(value, DIFFICULTY_GERMAN)
-def opt_difficulty_german_from_str(value):
+def opt_difficulty_german_from_str(value: str) -> Optional[int]:
return opt_from_str(value, difficulty_german_from_str)
-def opt_difficulty_german_to_str(value):
+def opt_difficulty_german_to_str(value: Optional[int]) -> str:
return opt_to_str(value, difficulty_german_to_str)
AVALANCHES_GERMAN = OrderedDict([(1, 'kaum'), (2, 'selten'), (3, 'gelegentlich'), (4, 'häufig')])
-def avalanches_german_from_str(value):
+def avalanches_german_from_str(value: str) -> int:
return dictkey_from_str(value, AVALANCHES_GERMAN)
-def avalanches_german_to_str(value):
+def avalanches_german_to_str(value: int) -> str:
return dictkey_to_str(value, AVALANCHES_GERMAN)
-def opt_avalanches_german_from_str(value):
+def opt_avalanches_german_from_str(value: str) -> Optional[int]:
return opt_from_str(value, avalanches_german_from_str)
-def opt_avalanches_german_to_str(value):
+def opt_avalanches_german_to_str(value: Optional[int]) -> str:
return opt_to_str(value, avalanches_german_to_str)
LIFT_GERMAN = ['Sessellift', 'Gondel', 'Linienbus', 'Taxi', 'Sonstige']
-def lift_german_from_str(value):
+def lift_german_from_str(value) -> Optional[List[Tuple[str, Optional[str]]]]:
"""Checks a lift_details property. It is a value comment property with the following
values allowed:
'Sessellift'
'Sessellift; Taxi' <=> [('Sessellift', None), ('Taxi', None)]
'Sessellift (Wochenende); Taxi (6 Euro)' <=> [('Sessellift', 'Wochenende'), ('Taxi', '6 Euro')]
"""
- return opt_no_german_from_str(value, lambda value_enum: enum_from_str(value_enum, lambda value_comment: value_comment_from_str(value_comment, lambda v: choice_from_str(v, LIFT_GERMAN), opt_str_from_str, comment_optional=True)), use_tuple=False, no_value=[], empty=None)
-
-
-def lift_german_to_str(value):
- return opt_no_german_to_str(value, lambda value_enum: enum_to_str(value_enum, lambda value_comment: value_comment_to_str(value_comment, str_to_str, opt_str_to_str, comment_optional=True)), use_tuple=False, no_value=[], empty=None)
+ return opt_no_german_from_str(
+ value,
+ lambda value_enum:
+ enum_from_str(
+ value_enum,
+ lambda value_comment:
+ value_comment_from_str(
+ value_comment,
+ lambda v: choice_from_str(v, LIFT_GERMAN),
+ opt_str_from_str,
+ comment_optional=True)
+ ), use_tuple=False, no_value=[], empty=None)
+
+
+def lift_german_to_str(value: Optional[List[Tuple[str, Optional[str]]]]) -> str:
+ return opt_no_german_to_str(
+ value,
+ lambda value_enum:
+ enum_to_str(
+ value_enum,
+ lambda value_comment:
+ value_comment_to_str(
+ value_comment,
+ str_to_str,
+ opt_str_to_str,
+ comment_optional=True)
+ ),
+ use_tuple=False, no_value=[], empty=None)
lift_german_converter = FromToConverter(lift_german_from_str, lift_german_to_str)
# public transport converter
# --------------------------
-PUBLIC_TRANSPORT_GERMAN = OrderedDict([(1, 'Sehr gut'), (2, 'Gut'), (3, 'Mittelmäßig'), (4, 'Schlecht'), (5, 'Nein'), (6, 'Ja')])
+PUBLIC_TRANSPORT_GERMAN = OrderedDict(
+ [(1, 'Sehr gut'), (2, 'Gut'), (3, 'Mittelmäßig'), (4, 'Schlecht'), (5, 'Nein'), (6, 'Ja')])
-def public_transport_german_from_str(value):
+def public_transport_german_from_str(value: str) -> int:
return dictkey_from_str(value, PUBLIC_TRANSPORT_GERMAN)
-def public_transport_german_to_str(value):
+def public_transport_german_to_str(value: int) -> str:
return dictkey_to_str(value, PUBLIC_TRANSPORT_GERMAN)
-def opt_public_transport_german_from_str(value):
+def opt_public_transport_german_from_str(value: str) -> Optional[int]:
return opt_from_str(value, public_transport_german_from_str)
-def opt_public_transport_german_to_str(value):
+def opt_public_transport_german_to_str(value: Optional[int]) -> str:
return opt_to_str(value, public_transport_german_to_str)
-opt_public_transport_german_converter = FromToConverter(opt_public_transport_german_from_str, opt_public_transport_german_to_str)
+opt_public_transport_german_converter = FromToConverter(opt_public_transport_german_from_str,
+ opt_public_transport_german_to_str)
# cachet converter
CACHET_REGEXP = [r'(Tiroler Naturrodelbahn-Gütesiegel) ([12]\d{3}) (leicht|mittel|schwer)$']
-def single_cachet_german_from_str(value):
+def single_cachet_german_from_str(value: str) -> Tuple[str, str, str]:
for pattern in CACHET_REGEXP:
match = re.match(pattern, value)
if match:
return match.groups()
- raise ValueError("'{}' is no valid cachet".format(value))
+ raise ValueError(f"'{value}' is no valid cachet")
-def single_cachet_german_to_str(value):
+def single_cachet_german_to_str(value: Tuple[str, str, str]) -> str:
return ' '.join(value)
# night light days converter
# --------------------------
-def nightlightdays_from_str(value):
- return value_comment_from_str(value, lambda val: opt_from_str(val, lambda v: int_from_str(v, min=0, max=7)), opt_str_from_str, comment_optional=True)
+def nightlightdays_from_str(value: str) -> Tuple[int, Optional[str]]:
+ return value_comment_from_str(
+ value,
+ lambda val:
+ opt_from_str(val, lambda v: int_from_str(v, minimum=0, maximum=7)), opt_str_from_str, comment_optional=True)
-def nightlightdays_to_str(value):
+def nightlightdays_to_str(value: Tuple[int, Optional[str]]) -> str:
return value_comment_to_str(value, lambda val: opt_to_str(val, int_to_str), opt_str_to_str, comment_optional=True)
# string with optional comment enum/list converter
# ------------------------------------------------
-def opt_str_opt_comment_enum_from_str(value):
+def opt_str_opt_comment_enum_from_str(value: str) -> Optional[List[Tuple[str, Optional[str]]]]:
"""The value can be an empty string, 'Nein' or a semicolon-separated list of strings with optional comments.
'' => None
'Nein' => []
'Talstation (nur mit Ticket); Schneealm' => [('Talstation', 'nur mit Ticket'), ('Schneealm', None)]"""
- return opt_no_german_from_str(value, lambda val: enum_from_str(val, lambda v: value_comment_from_str(v, req_str_from_str, opt_str_from_str, True)), False, [], None)
-
-
-def opt_str_opt_comment_enum_to_str(value):
- return opt_no_german_to_str(value, lambda val: enum_to_str(val, lambda v: value_comment_to_str(v, str_to_str, opt_str_to_str, True)), False, [], None)
+ return opt_no_german_from_str(
+ value,
+ lambda val:
+ enum_from_str(
+ val,
+ lambda v:
+ value_comment_from_str(v, req_str_from_str, opt_str_from_str, True)
+ ), False, [], None)
+
+
+def opt_str_opt_comment_enum_to_str(value: Optional[List[Tuple[str, Optional[str]]]]) -> str:
+ return opt_no_german_to_str(
+ value,
+ lambda val:
+ enum_to_str(
+ val, lambda v:
+ value_comment_to_str(v, str_to_str, opt_str_to_str, True)
+ ), False, [], None)
opt_str_opt_comment_enum_converter = FromToConverter(opt_str_opt_comment_enum_from_str, opt_str_opt_comment_enum_to_str)
RODELBAHNBOX_DICT = OrderedDict([
- ('Position', opt_lonlat_converter), # '47.583333 N 15.75 E'
- ('Position oben', opt_lonlat_converter), # '47.583333 N 15.75 E'
- ('Höhe oben', opt_uint_converter), # '2000'
- ('Position unten', opt_lonlat_converter), # '47.583333 N 15.75 E'
- ('Höhe unten', opt_uint_converter), # '1200'
- ('Länge', opt_uint_converter), # 3500
- ('Schwierigkeit', opt_difficulty_german_converter), # 'mittel'
- ('Lawinen', opt_avalanches_german_converter), # 'kaum'
- ('Betreiber', opt_str_converter), # 'Max Mustermann'
- ('Öffentliche Anreise', opt_public_transport_german_converter), # 'Mittelmäßig'
- ('Aufstieg möglich', opt_bool_german_converter), # 'Ja'
- ('Aufstieg getrennt', opt_tristate_german_comment_converter), # 'Ja'
- ('Gehzeit', opt_uint_converter), # 90
- ('Aufstiegshilfe', lift_german_converter), # 'Gondel (unterer Teil)'
+ ('Position', opt_lonlat_converter), # '47.583333 N 15.75 E'
+ ('Position oben', opt_lonlat_converter), # '47.583333 N 15.75 E'
+ ('Höhe oben', opt_uint_converter), # '2000'
+ ('Position unten', opt_lonlat_converter), # '47.583333 N 15.75 E'
+ ('Höhe unten', opt_uint_converter), # '1200'
+ ('Länge', opt_uint_converter), # 3500
+ ('Schwierigkeit', opt_difficulty_german_converter), # 'mittel'
+ ('Lawinen', opt_avalanches_german_converter), # 'kaum'
+ ('Betreiber', opt_str_converter), # 'Max Mustermann'
+ ('Öffentliche Anreise', opt_public_transport_german_converter), # 'Mittelmäßig'
+ ('Aufstieg möglich', opt_bool_german_converter), # 'Ja'
+ ('Aufstieg getrennt', opt_tristate_german_comment_converter), # 'Ja'
+ ('Gehzeit', opt_uint_converter), # 90
+ ('Aufstiegshilfe', lift_german_converter), # 'Gondel (unterer Teil)'
('Beleuchtungsanlage', opt_tristate_german_comment_converter),
- ('Beleuchtungstage', nightlightdays_converter), # '3 (Montag, Mittwoch, Freitag)'
- ('Rodelverleih', opt_str_opt_comment_enum_converter), # 'Talstation Serlesbahnan'
- ('Gütesiegel', cachet_german_converter), # 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'
- ('Webauskunft', webauskunft_converter), # 'http://www.nösslachhütte.at/page9.php'
- ('Telefonauskunft', opt_phone_comment_enum_converter), # '+43-664-5487520 (Mitterer Alm)'
+ ('Beleuchtungstage', nightlightdays_converter), # '3 (Montag, Mittwoch, Freitag)'
+ ('Rodelverleih', opt_str_opt_comment_enum_converter), # 'Talstation Serlesbahnan'
+ ('Gütesiegel', cachet_german_converter), # 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'
+ ('Webauskunft', webauskunft_converter), # 'http://www.nösslachhütte.at/page9.php'
+ ('Telefonauskunft', opt_phone_comment_enum_converter), # '+43-664-5487520 (Mitterer Alm)'
('Bild', opt_str_converter),
('In Übersichtskarte', opt_bool_german_converter),
('Forumid', opt_uint_converter)
def gasthausbox_from_template(template):
"""Returns an ordered dict."""
- return wikibox_from_template(template, GASTHAUSBOX_TEMPLATE_NAME, GASTHAUSBOX_DICT)
+ return wikibox_from_template(template, GASTHAUSBOX_DICT)
def gasthausbox_to_template(value):