forked from readthedocs/readthedocs.org
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidation.py
91 lines (71 loc) · 2.57 KB
/
validation.py
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
"""Validations for the RTD configuration file."""
import os
INVALID_BOOL = 'invalid-bool'
INVALID_CHOICE = 'invalid-choice'
INVALID_LIST = 'invalid-list'
INVALID_DICT = 'invalid-dictionary'
INVALID_PATH = 'invalid-path'
INVALID_STRING = 'invalid-string'
VALUE_NOT_FOUND = 'value-not-found'
class ValidationError(Exception):
"""Base error for validations."""
messages = {
INVALID_BOOL: 'expected one of (0, 1, true, false), got {value}',
INVALID_CHOICE: 'expected one of ({choices}), got {value}',
INVALID_DICT: '{value} is not a dictionary',
INVALID_PATH: 'path {value} does not exist',
INVALID_STRING: 'expected string',
INVALID_LIST: 'expected list',
VALUE_NOT_FOUND: '{value} not found',
}
def __init__(self, value, code, format_kwargs=None):
self.value = value
self.code = code
defaults = {
'value': value,
}
if format_kwargs is not None:
defaults.update(format_kwargs)
message = self.messages[code].format(**defaults)
super().__init__(message)
def validate_list(value):
"""Check if ``value`` is an iterable."""
if isinstance(value, (dict, str)):
raise ValidationError(value, INVALID_LIST)
if not hasattr(value, '__iter__'):
raise ValidationError(value, INVALID_LIST)
return list(value)
def validate_dict(value):
"""Check if ``value`` is a dictionary."""
if not isinstance(value, dict):
raise ValidationError(value, INVALID_DICT)
def validate_choice(value, choices):
"""Check that ``value`` is in ``choices``."""
choices = validate_list(choices)
if value not in choices:
raise ValidationError(
value,
INVALID_CHOICE,
{
'choices': ', '.join(map(str, choices)),
},
)
return value
def validate_bool(value):
"""Check that ``value`` is an boolean value."""
if value not in (0, 1, False, True):
raise ValidationError(value, INVALID_BOOL)
return bool(value)
def validate_path(value, base_path):
"""Check that ``value`` is a valid path name and normamlize it."""
string_value = validate_string(value)
if not string_value:
raise ValidationError(value, INVALID_PATH)
full_path = os.path.join(base_path, string_value)
rel_path = os.path.relpath(full_path, base_path)
return rel_path
def validate_string(value):
"""Check that ``value`` is a string type."""
if not isinstance(value, str):
raise ValidationError(value, INVALID_STRING)
return str(value)