Mercurial > hg
comparison mercurial/thirdparty/attr/validators.py @ 34397:765eb17a7eb8
thirdparty: vendor attrs
The attrs package allows defining namedtuple-like classes with no weird
behavior and no runtime performance cost.
This patch vendors in attrs 17.2.0.
# no-check-commit
Differential Revision: https://phab.mercurial-scm.org/D867
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Sun, 01 Oct 2017 04:14:16 -0700 |
parents | |
children | e1c586b9a43c |
comparison
equal
deleted
inserted
replaced
34396:9fb9f8440b71 | 34397:765eb17a7eb8 |
---|---|
1 """ | |
2 Commonly useful validators. | |
3 """ | |
4 | |
5 from __future__ import absolute_import, division, print_function | |
6 | |
7 from ._make import attr, attributes, and_, _AndValidator | |
8 | |
9 | |
10 __all__ = [ | |
11 "and_", | |
12 "in_", | |
13 "instance_of", | |
14 "optional", | |
15 "provides", | |
16 ] | |
17 | |
18 | |
19 @attributes(repr=False, slots=True, hash=True) | |
20 class _InstanceOfValidator(object): | |
21 type = attr() | |
22 | |
23 def __call__(self, inst, attr, value): | |
24 """ | |
25 We use a callable class to be able to change the ``__repr__``. | |
26 """ | |
27 if not isinstance(value, self.type): | |
28 raise TypeError( | |
29 "'{name}' must be {type!r} (got {value!r} that is a " | |
30 "{actual!r})." | |
31 .format(name=attr.name, type=self.type, | |
32 actual=value.__class__, value=value), | |
33 attr, self.type, value, | |
34 ) | |
35 | |
36 def __repr__(self): | |
37 return ( | |
38 "<instance_of validator for type {type!r}>" | |
39 .format(type=self.type) | |
40 ) | |
41 | |
42 | |
43 def instance_of(type): | |
44 """ | |
45 A validator that raises a :exc:`TypeError` if the initializer is called | |
46 with a wrong type for this particular attribute (checks are perfomed using | |
47 :func:`isinstance` therefore it's also valid to pass a tuple of types). | |
48 | |
49 :param type: The type to check for. | |
50 :type type: type or tuple of types | |
51 | |
52 :raises TypeError: With a human readable error message, the attribute | |
53 (of type :class:`attr.Attribute`), the expected type, and the value it | |
54 got. | |
55 """ | |
56 return _InstanceOfValidator(type) | |
57 | |
58 | |
59 @attributes(repr=False, slots=True, hash=True) | |
60 class _ProvidesValidator(object): | |
61 interface = attr() | |
62 | |
63 def __call__(self, inst, attr, value): | |
64 """ | |
65 We use a callable class to be able to change the ``__repr__``. | |
66 """ | |
67 if not self.interface.providedBy(value): | |
68 raise TypeError( | |
69 "'{name}' must provide {interface!r} which {value!r} " | |
70 "doesn't." | |
71 .format(name=attr.name, interface=self.interface, value=value), | |
72 attr, self.interface, value, | |
73 ) | |
74 | |
75 def __repr__(self): | |
76 return ( | |
77 "<provides validator for interface {interface!r}>" | |
78 .format(interface=self.interface) | |
79 ) | |
80 | |
81 | |
82 def provides(interface): | |
83 """ | |
84 A validator that raises a :exc:`TypeError` if the initializer is called | |
85 with an object that does not provide the requested *interface* (checks are | |
86 performed using ``interface.providedBy(value)`` (see `zope.interface | |
87 <https://zopeinterface.readthedocs.io/en/latest/>`_). | |
88 | |
89 :param zope.interface.Interface interface: The interface to check for. | |
90 | |
91 :raises TypeError: With a human readable error message, the attribute | |
92 (of type :class:`attr.Attribute`), the expected interface, and the | |
93 value it got. | |
94 """ | |
95 return _ProvidesValidator(interface) | |
96 | |
97 | |
98 @attributes(repr=False, slots=True, hash=True) | |
99 class _OptionalValidator(object): | |
100 validator = attr() | |
101 | |
102 def __call__(self, inst, attr, value): | |
103 if value is None: | |
104 return | |
105 | |
106 self.validator(inst, attr, value) | |
107 | |
108 def __repr__(self): | |
109 return ( | |
110 "<optional validator for {what} or None>" | |
111 .format(what=repr(self.validator)) | |
112 ) | |
113 | |
114 | |
115 def optional(validator): | |
116 """ | |
117 A validator that makes an attribute optional. An optional attribute is one | |
118 which can be set to ``None`` in addition to satisfying the requirements of | |
119 the sub-validator. | |
120 | |
121 :param validator: A validator (or a list of validators) that is used for | |
122 non-``None`` values. | |
123 :type validator: callable or :class:`list` of callables. | |
124 | |
125 .. versionadded:: 15.1.0 | |
126 .. versionchanged:: 17.1.0 *validator* can be a list of validators. | |
127 """ | |
128 if isinstance(validator, list): | |
129 return _OptionalValidator(_AndValidator(validator)) | |
130 return _OptionalValidator(validator) | |
131 | |
132 | |
133 @attributes(repr=False, slots=True, hash=True) | |
134 class _InValidator(object): | |
135 options = attr() | |
136 | |
137 def __call__(self, inst, attr, value): | |
138 if value not in self.options: | |
139 raise ValueError( | |
140 "'{name}' must be in {options!r} (got {value!r})" | |
141 .format(name=attr.name, options=self.options, value=value) | |
142 ) | |
143 | |
144 def __repr__(self): | |
145 return ( | |
146 "<in_ validator with options {options!r}>" | |
147 .format(options=self.options) | |
148 ) | |
149 | |
150 | |
151 def in_(options): | |
152 """ | |
153 A validator that raises a :exc:`ValueError` if the initializer is called | |
154 with a value that does not belong in the options provided. The check is | |
155 performed using ``value in options``. | |
156 | |
157 :param options: Allowed options. | |
158 :type options: list, tuple, :class:`enum.Enum`, ... | |
159 | |
160 :raises ValueError: With a human readable error message, the attribute (of | |
161 type :class:`attr.Attribute`), the expected options, and the value it | |
162 got. | |
163 | |
164 .. versionadded:: 17.1.0 | |
165 """ | |
166 return _InValidator(options) |