1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# ========================================================================== #
# #
# KVMD - The main PiKVM daemon. #
# #
# Copyright (C) 2018-2022 Maxim Devaev <[email protected]> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
# #
# ========================================================================== #
import re
from typing import List
from typing import Set
from typing import Mapping
from typing import Sequence
from typing import Callable
from typing import TypeVar
from typing import NoReturn
from typing import Union
from typing import Any
# =====
class ValidatorError(ValueError):
pass
# =====
_RetvalSeqT = TypeVar("_RetvalSeqT", bound=Sequence)
# =====
def raise_error(arg: Any, name: str, hide: bool=False) -> NoReturn:
arg_str = " "
if not hide:
arg_str = (f" {arg!r} " if isinstance(arg, (str, bytes)) else f" '{arg}' ")
raise ValidatorError(f"The argument{arg_str}is not a valid {name}")
def check_not_none(arg: Any, name: str) -> Any:
if arg is None:
raise ValidatorError(f"None argument is not a valid {name}")
return arg
def check_not_none_string(arg: Any, name: str, strip: bool=True) -> str:
arg = str(check_not_none(arg, name))
if strip:
arg = arg.strip()
return arg
def check_in_list(arg: Any, name: str, variants: Union[Sequence, Mapping, Set]) -> Any:
if arg not in variants:
raise_error(arg, name)
return arg
def check_string_in_list(
arg: Any,
name: str,
variants: Union[Sequence[str], Mapping[str, Any], Set[str]],
lower: bool=True,
) -> str:
arg = check_not_none_string(arg, name)
if lower:
arg = arg.lower()
return check_in_list(arg, name, variants)
def check_re_match(arg: Any, name: str, pattern: str, strip: bool=True, hide: bool=False) -> str:
arg = check_not_none_string(arg, name, strip=strip)
if re.match(pattern, arg, flags=re.MULTILINE) is None:
raise_error(arg, name, hide=hide)
return arg
def check_len(arg: _RetvalSeqT, name: str, limit: int) -> _RetvalSeqT:
if len(arg) > limit:
raise_error(arg, name)
return arg
def check_any(arg: Any, name: str, validators: List[Callable[[Any], Any]]) -> Any: # pylint: disable=inconsistent-return-statements
for validator in validators:
try:
return validator(arg)
except Exception:
pass
raise_error(arg, name)
|