author | Matt Harbison <matt_harbison@yahoo.com> |
Mon, 21 Nov 2022 15:04:42 -0500 | |
changeset 49643 | e1c586b9a43c |
parent 34397 | 765eb17a7eb8 |
permissions | -rw-r--r-- |
49643
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
1 |
# SPDX-License-Identifier: MIT |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
2 |
|
34397 | 3 |
""" |
4 |
Commonly useful converters. |
|
5 |
""" |
|
6 |
||
49643
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
7 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
8 |
import typing |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
9 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
10 |
from ._compat import _AnnotationExtractor |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
11 |
from ._make import NOTHING, Factory, pipe |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
12 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
13 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
14 |
__all__ = [ |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
15 |
"default_if_none", |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
16 |
"optional", |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
17 |
"pipe", |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
18 |
"to_bool", |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
19 |
] |
34397 | 20 |
|
21 |
||
22 |
def optional(converter): |
|
23 |
""" |
|
24 |
A converter that allows an attribute to be optional. An optional attribute |
|
25 |
is one which can be set to ``None``. |
|
26 |
||
49643
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
27 |
Type annotations will be inferred from the wrapped converter's, if it |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
28 |
has any. |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
29 |
|
34397 | 30 |
:param callable converter: the converter that is used for non-``None`` |
31 |
values. |
|
32 |
||
49643
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
33 |
.. versionadded:: 17.1.0 |
34397 | 34 |
""" |
35 |
||
36 |
def optional_converter(val): |
|
37 |
if val is None: |
|
38 |
return None |
|
39 |
return converter(val) |
|
40 |
||
49643
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
41 |
xtr = _AnnotationExtractor(converter) |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
42 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
43 |
t = xtr.get_first_param_type() |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
44 |
if t: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
45 |
optional_converter.__annotations__["val"] = typing.Optional[t] |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
46 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
47 |
rt = xtr.get_return_type() |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
48 |
if rt: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
49 |
optional_converter.__annotations__["return"] = typing.Optional[rt] |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
50 |
|
34397 | 51 |
return optional_converter |
49643
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
52 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
53 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
54 |
def default_if_none(default=NOTHING, factory=None): |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
55 |
""" |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
56 |
A converter that allows to replace ``None`` values by *default* or the |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
57 |
result of *factory*. |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
58 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
59 |
:param default: Value to be used if ``None`` is passed. Passing an instance |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
60 |
of `attrs.Factory` is supported, however the ``takes_self`` option |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
61 |
is *not*. |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
62 |
:param callable factory: A callable that takes no parameters whose result |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
63 |
is used if ``None`` is passed. |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
64 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
65 |
:raises TypeError: If **neither** *default* or *factory* is passed. |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
66 |
:raises TypeError: If **both** *default* and *factory* are passed. |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
67 |
:raises ValueError: If an instance of `attrs.Factory` is passed with |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
68 |
``takes_self=True``. |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
69 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
70 |
.. versionadded:: 18.2.0 |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
71 |
""" |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
72 |
if default is NOTHING and factory is None: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
73 |
raise TypeError("Must pass either `default` or `factory`.") |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
74 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
75 |
if default is not NOTHING and factory is not None: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
76 |
raise TypeError( |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
77 |
"Must pass either `default` or `factory` but not both." |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
78 |
) |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
79 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
80 |
if factory is not None: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
81 |
default = Factory(factory) |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
82 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
83 |
if isinstance(default, Factory): |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
84 |
if default.takes_self: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
85 |
raise ValueError( |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
86 |
"`takes_self` is not supported by default_if_none." |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
87 |
) |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
88 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
89 |
def default_if_none_converter(val): |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
90 |
if val is not None: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
91 |
return val |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
92 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
93 |
return default.factory() |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
94 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
95 |
else: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
96 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
97 |
def default_if_none_converter(val): |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
98 |
if val is not None: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
99 |
return val |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
100 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
101 |
return default |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
102 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
103 |
return default_if_none_converter |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
104 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
105 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
106 |
def to_bool(val): |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
107 |
""" |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
108 |
Convert "boolean" strings (e.g., from env. vars.) to real booleans. |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
109 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
110 |
Values mapping to :code:`True`: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
111 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
112 |
- :code:`True` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
113 |
- :code:`"true"` / :code:`"t"` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
114 |
- :code:`"yes"` / :code:`"y"` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
115 |
- :code:`"on"` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
116 |
- :code:`"1"` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
117 |
- :code:`1` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
118 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
119 |
Values mapping to :code:`False`: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
120 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
121 |
- :code:`False` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
122 |
- :code:`"false"` / :code:`"f"` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
123 |
- :code:`"no"` / :code:`"n"` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
124 |
- :code:`"off"` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
125 |
- :code:`"0"` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
126 |
- :code:`0` |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
127 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
128 |
:raises ValueError: for any other value. |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
129 |
|
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
130 |
.. versionadded:: 21.3.0 |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
131 |
""" |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
132 |
if isinstance(val, str): |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
133 |
val = val.lower() |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
134 |
truthy = {True, "true", "t", "yes", "y", "on", "1", 1} |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
135 |
falsy = {False, "false", "f", "no", "n", "off", "0", 0} |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
136 |
try: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
137 |
if val in truthy: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
138 |
return True |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
139 |
if val in falsy: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
140 |
return False |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
141 |
except TypeError: |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
142 |
# Raised when "val" is not hashable (e.g., lists) |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
143 |
pass |
e1c586b9a43c
attr: vendor 22.1.0
Matt Harbison <matt_harbison@yahoo.com>
parents:
34397
diff
changeset
|
144 |
raise ValueError("Cannot convert value to bool: {}".format(val)) |