envbool 0.3.0__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {envbool-0.3.0 → envbool-0.4.1}/PKG-INFO +58 -61
- {envbool-0.3.0 → envbool-0.4.1}/README.md +56 -58
- envbool-0.4.1/pyproject.toml +121 -0
- envbool-0.3.0/pyproject.toml → envbool-0.4.1/pyproject.toml.orig +9 -6
- {envbool-0.3.0 → envbool-0.4.1}/src/envbool/__init__.py +16 -11
- {envbool-0.3.0 → envbool-0.4.1}/src/envbool/_cli.py +32 -68
- {envbool-0.3.0 → envbool-0.4.1}/src/envbool/_core.py +26 -55
- envbool-0.4.1/src/envbool/_defaults.py +189 -0
- {envbool-0.3.0 → envbool-0.4.1}/src/envbool/_env.py +5 -4
- {envbool-0.3.0 → envbool-0.4.1}/src/envbool/exceptions.py +5 -14
- envbool-0.3.0/src/envbool/_config.py +0 -391
- envbool-0.3.0/src/envbool/_defaults.py +0 -14
- {envbool-0.3.0 → envbool-0.4.1}/src/envbool/__main__.py +0 -0
- {envbool-0.3.0 → envbool-0.4.1}/src/envbool/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: envbool
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: A small Python library and CLI tool for coercing environment variables (and arbitrary strings) into boolean values.
|
|
5
5
|
Keywords: environment variables,boolean,configuration,env,coerce
|
|
6
6
|
Author: Kyle O'Malley
|
|
@@ -18,12 +18,11 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.14
|
|
20
20
|
Classifier: Typing :: Typed
|
|
21
|
-
Requires-Dist: platformdirs>=4.9.6
|
|
22
21
|
Requires-Python: >=3.11
|
|
23
22
|
Project-URL: Homepage, https://github.com/jkomalley/envbool
|
|
24
23
|
Project-URL: Repository, https://github.com/jkomalley/envbool
|
|
25
24
|
Project-URL: Issues, https://github.com/jkomalley/envbool/issues
|
|
26
|
-
Project-URL: Changelog, https://github.com/jkomalley/envbool/
|
|
25
|
+
Project-URL: Changelog, https://github.com/jkomalley/envbool/blob/main/CHANGELOG.md
|
|
27
26
|
Description-Content-Type: text/markdown
|
|
28
27
|
|
|
29
28
|
<div align="center">
|
|
@@ -67,18 +66,17 @@ CACHE = envbool("CACHE")
|
|
|
67
66
|
- **Always returns `bool`.** No `None`, no surprises in your type signatures.
|
|
68
67
|
- **Customizable value sets.** Replace or extend the truthy/falsy words your
|
|
69
68
|
environment uses.
|
|
70
|
-
- **
|
|
71
|
-
|
|
69
|
+
- **Process-level defaults.** Call `set_defaults()` once at startup instead
|
|
70
|
+
of threading options through every call site.
|
|
72
71
|
- **A CLI for shell scripts.** Exit codes map to truthiness, so it drops
|
|
73
72
|
straight into `&&` / `||` chains.
|
|
74
|
-
- **Zero ceremony.**
|
|
73
|
+
- **Zero ceremony.** Zero dependencies, fully typed, Python 3.11+.
|
|
75
74
|
|
|
76
75
|
## Contents
|
|
77
76
|
|
|
78
77
|
- [Installation](#installation)
|
|
79
78
|
- [Usage](#usage)
|
|
80
79
|
- [Command-line interface](#command-line-interface)
|
|
81
|
-
- [Configuration](#configuration)
|
|
82
80
|
- [API reference](#api-reference)
|
|
83
81
|
- [Advanced topics](#advanced-topics)
|
|
84
82
|
- [Contributing](#contributing)
|
|
@@ -151,6 +149,37 @@ to_bool("0") # False
|
|
|
151
149
|
to_bool("maybe", strict=True) # raises InvalidBoolValueError
|
|
152
150
|
```
|
|
153
151
|
|
|
152
|
+
### Process-level defaults
|
|
153
|
+
|
|
154
|
+
Set policy once at startup instead of threading `strict=`/`extend_truthy=`
|
|
155
|
+
through every call site:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
import envbool
|
|
159
|
+
|
|
160
|
+
envbool.set_defaults(strict=True, extend_truthy=["enabled"])
|
|
161
|
+
|
|
162
|
+
envbool.envbool("DEBUG") # now raises on unrecognized values by default
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`set_defaults()` replaces the process-level defaults **from the built-ins**,
|
|
166
|
+
not from whatever a previous `set_defaults()` call left in place — call it
|
|
167
|
+
once. Call-site arguments (`envbool("X", strict=False)`) still override
|
|
168
|
+
whatever `set_defaults()` configured:
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
built-in defaults → set_defaults() → function arguments / CLI flags
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`get_defaults()` returns the active `Defaults` (a frozen dataclass: `strict`,
|
|
175
|
+
`warn`, `effective_truthy`, `effective_falsy`) for inspection.
|
|
176
|
+
`reset_defaults()` restores the built-ins — call it in a test fixture (see
|
|
177
|
+
[Testing code that uses envbool](#testing-code-that-uses-envbool)).
|
|
178
|
+
|
|
179
|
+
> Through 0.3.x, envbool read TOML config files (`envbool.toml`,
|
|
180
|
+
> `[tool.envbool]`). 0.4.0 removed them in favor of `set_defaults()` — see
|
|
181
|
+
> `CHANGELOG.md` for the rationale and migration note.
|
|
182
|
+
|
|
154
183
|
## Command-line interface
|
|
155
184
|
|
|
156
185
|
The `envbool` command exits `0` for truthy, `1` for falsy, and `2` on error, so
|
|
@@ -176,9 +205,9 @@ in that order of priority.
|
|
|
176
205
|
|
|
177
206
|
```console
|
|
178
207
|
$ envbool --help
|
|
179
|
-
usage: envbool [-h] [--value TEXT] [--strict] [--warn] [--default]
|
|
180
|
-
[--
|
|
181
|
-
[--extend-
|
|
208
|
+
usage: envbool [-h] [--value TEXT] [--strict] [--warn] [--default]
|
|
209
|
+
[--required] [--print] [--truthy VALUE] [--falsy VALUE]
|
|
210
|
+
[--extend-truthy VALUE] [--extend-falsy VALUE]
|
|
182
211
|
[VAR_NAME]
|
|
183
212
|
|
|
184
213
|
Coerce an environment variable or string to a boolean.
|
|
@@ -192,48 +221,25 @@ options:
|
|
|
192
221
|
--strict, -s Raise error on unrecognized values.
|
|
193
222
|
--warn Log a warning on unrecognized values.
|
|
194
223
|
--default, -d Default value if unset/empty (default: false).
|
|
224
|
+
--required, -r Exit 2 if VAR_NAME is not set in the environment.
|
|
195
225
|
--print, -p Print "true" or "false" instead of using exit codes.
|
|
196
226
|
--truthy VALUE Replace the truthy set with VALUE (repeatable).
|
|
197
227
|
--falsy VALUE Replace the falsy set with VALUE (repeatable).
|
|
198
228
|
--extend-truthy VALUE
|
|
199
229
|
Add VALUE to the truthy set (repeatable).
|
|
200
230
|
--extend-falsy VALUE Add VALUE to the falsy set (repeatable).
|
|
201
|
-
--show-config Print the effective configuration and exit.
|
|
202
231
|
```
|
|
203
232
|
|
|
204
233
|
A few rules worth knowing:
|
|
205
234
|
|
|
206
|
-
- Omitting `--strict` / `--warn`
|
|
235
|
+
- Omitting `--strict` / `--warn` uses the built-in defaults (lenient, no
|
|
236
|
+
warnings). `set_defaults()` is a library-level concern — the one-shot CLI
|
|
237
|
+
process doesn't read it.
|
|
207
238
|
- `VAR_NAME` and `--value` are mutually exclusive.
|
|
208
|
-
- `--
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
## Configuration
|
|
214
|
-
|
|
215
|
-
Share defaults across a project by dropping an `envbool.toml` at its root (or a
|
|
216
|
-
`[tool.envbool]` table in `pyproject.toml`):
|
|
217
|
-
|
|
218
|
-
```toml
|
|
219
|
-
# envbool.toml
|
|
220
|
-
strict = true
|
|
221
|
-
extend_truthy = ["enabled"]
|
|
222
|
-
extend_falsy = ["disabled"]
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
`envbool` walks up from the current directory to find the nearest project config,
|
|
226
|
-
then falls back to a user-level `config.toml` in the platform's standard config
|
|
227
|
-
directory (`~/.config/envbool/` on Linux, `~/Library/Application Support/envbool/`
|
|
228
|
-
on macOS), resolved via [platformdirs](https://pypi.org/project/platformdirs/).
|
|
229
|
-
|
|
230
|
-
Values resolve in three layers, each overriding the last:
|
|
231
|
-
|
|
232
|
-
```
|
|
233
|
-
built-in defaults → config file → function arguments / CLI flags
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
Set `ENVBOOL_NO_CONFIG=1` to skip config discovery entirely.
|
|
239
|
+
- `--required` only applies to `VAR_NAME`; combining it with `--value` or
|
|
240
|
+
giving it no `VAR_NAME` at all is a usage error.
|
|
241
|
+
- With no `VAR_NAME`, `--value`, or non-empty piped stdin, the CLI prints
|
|
242
|
+
usage and exits `2`.
|
|
237
243
|
|
|
238
244
|
## API reference
|
|
239
245
|
|
|
@@ -241,23 +247,23 @@ Set `ENVBOOL_NO_CONFIG=1` to skip config discovery entirely.
|
|
|
241
247
|
| --- | --- |
|
|
242
248
|
| `envbool(var, **opts)` | Read an environment variable and return `bool`. |
|
|
243
249
|
| `to_bool(value, **opts)` | Coerce a string to `bool`. |
|
|
244
|
-
| `
|
|
245
|
-
| `
|
|
246
|
-
| `
|
|
250
|
+
| `set_defaults(**opts)` | Set process-level strict/warn/truthy/falsy defaults, replacing the built-ins. |
|
|
251
|
+
| `get_defaults()` | Return the active `Defaults`. |
|
|
252
|
+
| `reset_defaults()` | Restore built-in defaults. |
|
|
253
|
+
| `Defaults` | Frozen dataclass: `strict`, `warn`, `effective_truthy`, `effective_falsy`. |
|
|
247
254
|
| `DEFAULT_TRUTHY` | `frozenset` of the built-in truthy strings. |
|
|
248
255
|
| `DEFAULT_FALSY` | `frozenset` of the built-in falsy strings. |
|
|
249
256
|
| `EnvBoolError` | Base class for every exception the library raises. |
|
|
250
257
|
| `InvalidBoolValueError` | Raised in strict mode for unrecognized values. Also a `ValueError`. |
|
|
251
258
|
| `MissingEnvVarError` | Raised by `envbool(required=True)` when the variable is unset. Also a `KeyError`. |
|
|
252
|
-
| `ConfigError` | Raised when a config file is malformed. |
|
|
253
259
|
|
|
254
260
|
`envbool()` and `to_bool()` share the same keyword-only options:
|
|
255
261
|
|
|
256
262
|
| Option | Type | Default | Meaning |
|
|
257
263
|
| --- | --- | --- | --- |
|
|
258
264
|
| `default` | `bool` | `False` | Returned for unset/empty input. |
|
|
259
|
-
| `strict` | `bool \| None` | `None` | Raise on unrecognized values (`None` defers to
|
|
260
|
-
| `warn` | `bool \| None` | `None` | Log a warning on unrecognized values (`None` defers to
|
|
265
|
+
| `strict` | `bool \| None` | `None` | Raise on unrecognized values (`None` defers to `set_defaults()`). |
|
|
266
|
+
| `warn` | `bool \| None` | `None` | Log a warning on unrecognized values (`None` defers to `set_defaults()`). |
|
|
261
267
|
| `truthy` / `falsy` | `Iterable[str] \| None` | `None` | **Replace** the effective set. |
|
|
262
268
|
| `extend_truthy` / `extend_falsy` | `Iterable[str] \| None` | `None` | **Extend** the effective set. |
|
|
263
269
|
|
|
@@ -294,10 +300,6 @@ InvalidBoolValueError: Invalid boolean value for MY_VAR: 'maybe'
|
|
|
294
300
|
Expected falsy: 0, false, no, off
|
|
295
301
|
```
|
|
296
302
|
|
|
297
|
-
`ConfigError` is raised when a config file is found but malformed (for example,
|
|
298
|
-
`strict = "yes"` instead of `strict = true`). It carries the offending path on
|
|
299
|
-
`e.path`.
|
|
300
|
-
|
|
301
303
|
### Logging
|
|
302
304
|
|
|
303
305
|
`envbool` logs through the standard `logging` module under the `"envbool"`
|
|
@@ -313,7 +315,6 @@ logging.getLogger("envbool").addHandler(logging.StreamHandler())
|
|
|
313
315
|
|
|
314
316
|
| Level | When |
|
|
315
317
|
| --- | --- |
|
|
316
|
-
| `DEBUG` | A config file was discovered and loaded, or none was found. |
|
|
317
318
|
| `WARNING` | An unrecognized value fell through in lenient mode (only when `warn=True`). |
|
|
318
319
|
| `WARNING` | The truthy and falsy sets overlap (truthy wins). |
|
|
319
320
|
|
|
@@ -336,24 +337,20 @@ else:
|
|
|
336
337
|
|
|
337
338
|
### Testing code that uses envbool
|
|
338
339
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
autouse fixture:
|
|
340
|
+
If your tests call `set_defaults()`, reset it between tests with an autouse
|
|
341
|
+
fixture so overrides don't leak across the suite:
|
|
342
342
|
|
|
343
343
|
```python
|
|
344
344
|
# conftest.py
|
|
345
345
|
import pytest
|
|
346
|
-
from envbool
|
|
346
|
+
from envbool import reset_defaults
|
|
347
347
|
|
|
348
348
|
@pytest.fixture(autouse=True)
|
|
349
|
-
def
|
|
349
|
+
def _reset_envbool_defaults():
|
|
350
350
|
yield
|
|
351
|
-
|
|
351
|
+
reset_defaults()
|
|
352
352
|
```
|
|
353
353
|
|
|
354
|
-
`_reset_config()` is private but stable and exists for exactly this purpose; it
|
|
355
|
-
clears the cache under a lock, so it is safe to call from any thread.
|
|
356
|
-
|
|
357
354
|
## Contributing
|
|
358
355
|
|
|
359
356
|
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for development
|
|
@@ -39,18 +39,17 @@ CACHE = envbool("CACHE")
|
|
|
39
39
|
- **Always returns `bool`.** No `None`, no surprises in your type signatures.
|
|
40
40
|
- **Customizable value sets.** Replace or extend the truthy/falsy words your
|
|
41
41
|
environment uses.
|
|
42
|
-
- **
|
|
43
|
-
|
|
42
|
+
- **Process-level defaults.** Call `set_defaults()` once at startup instead
|
|
43
|
+
of threading options through every call site.
|
|
44
44
|
- **A CLI for shell scripts.** Exit codes map to truthiness, so it drops
|
|
45
45
|
straight into `&&` / `||` chains.
|
|
46
|
-
- **Zero ceremony.**
|
|
46
|
+
- **Zero ceremony.** Zero dependencies, fully typed, Python 3.11+.
|
|
47
47
|
|
|
48
48
|
## Contents
|
|
49
49
|
|
|
50
50
|
- [Installation](#installation)
|
|
51
51
|
- [Usage](#usage)
|
|
52
52
|
- [Command-line interface](#command-line-interface)
|
|
53
|
-
- [Configuration](#configuration)
|
|
54
53
|
- [API reference](#api-reference)
|
|
55
54
|
- [Advanced topics](#advanced-topics)
|
|
56
55
|
- [Contributing](#contributing)
|
|
@@ -123,6 +122,37 @@ to_bool("0") # False
|
|
|
123
122
|
to_bool("maybe", strict=True) # raises InvalidBoolValueError
|
|
124
123
|
```
|
|
125
124
|
|
|
125
|
+
### Process-level defaults
|
|
126
|
+
|
|
127
|
+
Set policy once at startup instead of threading `strict=`/`extend_truthy=`
|
|
128
|
+
through every call site:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
import envbool
|
|
132
|
+
|
|
133
|
+
envbool.set_defaults(strict=True, extend_truthy=["enabled"])
|
|
134
|
+
|
|
135
|
+
envbool.envbool("DEBUG") # now raises on unrecognized values by default
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`set_defaults()` replaces the process-level defaults **from the built-ins**,
|
|
139
|
+
not from whatever a previous `set_defaults()` call left in place — call it
|
|
140
|
+
once. Call-site arguments (`envbool("X", strict=False)`) still override
|
|
141
|
+
whatever `set_defaults()` configured:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
built-in defaults → set_defaults() → function arguments / CLI flags
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`get_defaults()` returns the active `Defaults` (a frozen dataclass: `strict`,
|
|
148
|
+
`warn`, `effective_truthy`, `effective_falsy`) for inspection.
|
|
149
|
+
`reset_defaults()` restores the built-ins — call it in a test fixture (see
|
|
150
|
+
[Testing code that uses envbool](#testing-code-that-uses-envbool)).
|
|
151
|
+
|
|
152
|
+
> Through 0.3.x, envbool read TOML config files (`envbool.toml`,
|
|
153
|
+
> `[tool.envbool]`). 0.4.0 removed them in favor of `set_defaults()` — see
|
|
154
|
+
> `CHANGELOG.md` for the rationale and migration note.
|
|
155
|
+
|
|
126
156
|
## Command-line interface
|
|
127
157
|
|
|
128
158
|
The `envbool` command exits `0` for truthy, `1` for falsy, and `2` on error, so
|
|
@@ -148,9 +178,9 @@ in that order of priority.
|
|
|
148
178
|
|
|
149
179
|
```console
|
|
150
180
|
$ envbool --help
|
|
151
|
-
usage: envbool [-h] [--value TEXT] [--strict] [--warn] [--default]
|
|
152
|
-
[--
|
|
153
|
-
[--extend-
|
|
181
|
+
usage: envbool [-h] [--value TEXT] [--strict] [--warn] [--default]
|
|
182
|
+
[--required] [--print] [--truthy VALUE] [--falsy VALUE]
|
|
183
|
+
[--extend-truthy VALUE] [--extend-falsy VALUE]
|
|
154
184
|
[VAR_NAME]
|
|
155
185
|
|
|
156
186
|
Coerce an environment variable or string to a boolean.
|
|
@@ -164,48 +194,25 @@ options:
|
|
|
164
194
|
--strict, -s Raise error on unrecognized values.
|
|
165
195
|
--warn Log a warning on unrecognized values.
|
|
166
196
|
--default, -d Default value if unset/empty (default: false).
|
|
197
|
+
--required, -r Exit 2 if VAR_NAME is not set in the environment.
|
|
167
198
|
--print, -p Print "true" or "false" instead of using exit codes.
|
|
168
199
|
--truthy VALUE Replace the truthy set with VALUE (repeatable).
|
|
169
200
|
--falsy VALUE Replace the falsy set with VALUE (repeatable).
|
|
170
201
|
--extend-truthy VALUE
|
|
171
202
|
Add VALUE to the truthy set (repeatable).
|
|
172
203
|
--extend-falsy VALUE Add VALUE to the falsy set (repeatable).
|
|
173
|
-
--show-config Print the effective configuration and exit.
|
|
174
204
|
```
|
|
175
205
|
|
|
176
206
|
A few rules worth knowing:
|
|
177
207
|
|
|
178
|
-
- Omitting `--strict` / `--warn`
|
|
208
|
+
- Omitting `--strict` / `--warn` uses the built-in defaults (lenient, no
|
|
209
|
+
warnings). `set_defaults()` is a library-level concern — the one-shot CLI
|
|
210
|
+
process doesn't read it.
|
|
179
211
|
- `VAR_NAME` and `--value` are mutually exclusive.
|
|
180
|
-
- `--
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
## Configuration
|
|
186
|
-
|
|
187
|
-
Share defaults across a project by dropping an `envbool.toml` at its root (or a
|
|
188
|
-
`[tool.envbool]` table in `pyproject.toml`):
|
|
189
|
-
|
|
190
|
-
```toml
|
|
191
|
-
# envbool.toml
|
|
192
|
-
strict = true
|
|
193
|
-
extend_truthy = ["enabled"]
|
|
194
|
-
extend_falsy = ["disabled"]
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
`envbool` walks up from the current directory to find the nearest project config,
|
|
198
|
-
then falls back to a user-level `config.toml` in the platform's standard config
|
|
199
|
-
directory (`~/.config/envbool/` on Linux, `~/Library/Application Support/envbool/`
|
|
200
|
-
on macOS), resolved via [platformdirs](https://pypi.org/project/platformdirs/).
|
|
201
|
-
|
|
202
|
-
Values resolve in three layers, each overriding the last:
|
|
203
|
-
|
|
204
|
-
```
|
|
205
|
-
built-in defaults → config file → function arguments / CLI flags
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
Set `ENVBOOL_NO_CONFIG=1` to skip config discovery entirely.
|
|
212
|
+
- `--required` only applies to `VAR_NAME`; combining it with `--value` or
|
|
213
|
+
giving it no `VAR_NAME` at all is a usage error.
|
|
214
|
+
- With no `VAR_NAME`, `--value`, or non-empty piped stdin, the CLI prints
|
|
215
|
+
usage and exits `2`.
|
|
209
216
|
|
|
210
217
|
## API reference
|
|
211
218
|
|
|
@@ -213,23 +220,23 @@ Set `ENVBOOL_NO_CONFIG=1` to skip config discovery entirely.
|
|
|
213
220
|
| --- | --- |
|
|
214
221
|
| `envbool(var, **opts)` | Read an environment variable and return `bool`. |
|
|
215
222
|
| `to_bool(value, **opts)` | Coerce a string to `bool`. |
|
|
216
|
-
| `
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
223
|
+
| `set_defaults(**opts)` | Set process-level strict/warn/truthy/falsy defaults, replacing the built-ins. |
|
|
224
|
+
| `get_defaults()` | Return the active `Defaults`. |
|
|
225
|
+
| `reset_defaults()` | Restore built-in defaults. |
|
|
226
|
+
| `Defaults` | Frozen dataclass: `strict`, `warn`, `effective_truthy`, `effective_falsy`. |
|
|
219
227
|
| `DEFAULT_TRUTHY` | `frozenset` of the built-in truthy strings. |
|
|
220
228
|
| `DEFAULT_FALSY` | `frozenset` of the built-in falsy strings. |
|
|
221
229
|
| `EnvBoolError` | Base class for every exception the library raises. |
|
|
222
230
|
| `InvalidBoolValueError` | Raised in strict mode for unrecognized values. Also a `ValueError`. |
|
|
223
231
|
| `MissingEnvVarError` | Raised by `envbool(required=True)` when the variable is unset. Also a `KeyError`. |
|
|
224
|
-
| `ConfigError` | Raised when a config file is malformed. |
|
|
225
232
|
|
|
226
233
|
`envbool()` and `to_bool()` share the same keyword-only options:
|
|
227
234
|
|
|
228
235
|
| Option | Type | Default | Meaning |
|
|
229
236
|
| --- | --- | --- | --- |
|
|
230
237
|
| `default` | `bool` | `False` | Returned for unset/empty input. |
|
|
231
|
-
| `strict` | `bool \| None` | `None` | Raise on unrecognized values (`None` defers to
|
|
232
|
-
| `warn` | `bool \| None` | `None` | Log a warning on unrecognized values (`None` defers to
|
|
238
|
+
| `strict` | `bool \| None` | `None` | Raise on unrecognized values (`None` defers to `set_defaults()`). |
|
|
239
|
+
| `warn` | `bool \| None` | `None` | Log a warning on unrecognized values (`None` defers to `set_defaults()`). |
|
|
233
240
|
| `truthy` / `falsy` | `Iterable[str] \| None` | `None` | **Replace** the effective set. |
|
|
234
241
|
| `extend_truthy` / `extend_falsy` | `Iterable[str] \| None` | `None` | **Extend** the effective set. |
|
|
235
242
|
|
|
@@ -266,10 +273,6 @@ InvalidBoolValueError: Invalid boolean value for MY_VAR: 'maybe'
|
|
|
266
273
|
Expected falsy: 0, false, no, off
|
|
267
274
|
```
|
|
268
275
|
|
|
269
|
-
`ConfigError` is raised when a config file is found but malformed (for example,
|
|
270
|
-
`strict = "yes"` instead of `strict = true`). It carries the offending path on
|
|
271
|
-
`e.path`.
|
|
272
|
-
|
|
273
276
|
### Logging
|
|
274
277
|
|
|
275
278
|
`envbool` logs through the standard `logging` module under the `"envbool"`
|
|
@@ -285,7 +288,6 @@ logging.getLogger("envbool").addHandler(logging.StreamHandler())
|
|
|
285
288
|
|
|
286
289
|
| Level | When |
|
|
287
290
|
| --- | --- |
|
|
288
|
-
| `DEBUG` | A config file was discovered and loaded, or none was found. |
|
|
289
291
|
| `WARNING` | An unrecognized value fell through in lenient mode (only when `warn=True`). |
|
|
290
292
|
| `WARNING` | The truthy and falsy sets overlap (truthy wins). |
|
|
291
293
|
|
|
@@ -308,24 +310,20 @@ else:
|
|
|
308
310
|
|
|
309
311
|
### Testing code that uses envbool
|
|
310
312
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
autouse fixture:
|
|
313
|
+
If your tests call `set_defaults()`, reset it between tests with an autouse
|
|
314
|
+
fixture so overrides don't leak across the suite:
|
|
314
315
|
|
|
315
316
|
```python
|
|
316
317
|
# conftest.py
|
|
317
318
|
import pytest
|
|
318
|
-
from envbool
|
|
319
|
+
from envbool import reset_defaults
|
|
319
320
|
|
|
320
321
|
@pytest.fixture(autouse=True)
|
|
321
|
-
def
|
|
322
|
+
def _reset_envbool_defaults():
|
|
322
323
|
yield
|
|
323
|
-
|
|
324
|
+
reset_defaults()
|
|
324
325
|
```
|
|
325
326
|
|
|
326
|
-
`_reset_config()` is private but stable and exists for exactly this purpose; it
|
|
327
|
-
clears the cache under a lock, so it is safe to call from any thread.
|
|
328
|
-
|
|
329
327
|
## Contributing
|
|
330
328
|
|
|
331
329
|
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for development
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "envbool"
|
|
3
|
+
version = "0.4.1"
|
|
4
|
+
description = "A small Python library and CLI tool for coercing environment variables (and arbitrary strings) into boolean values."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
keywords = [
|
|
9
|
+
"environment variables",
|
|
10
|
+
"boolean",
|
|
11
|
+
"configuration",
|
|
12
|
+
"env",
|
|
13
|
+
"coerce",
|
|
14
|
+
]
|
|
15
|
+
dependencies = []
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
20
|
+
"Topic :: Utilities",
|
|
21
|
+
"Environment :: Console",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Programming Language :: Python :: 3.14",
|
|
28
|
+
"Typing :: Typed",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[[project.authors]]
|
|
32
|
+
name = "Kyle O'Malley"
|
|
33
|
+
email = "j.kyle.omalley@gmail.com"
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://github.com/jkomalley/envbool"
|
|
37
|
+
Repository = "https://github.com/jkomalley/envbool"
|
|
38
|
+
Issues = "https://github.com/jkomalley/envbool/issues"
|
|
39
|
+
Changelog = "https://github.com/jkomalley/envbool/blob/main/CHANGELOG.md"
|
|
40
|
+
|
|
41
|
+
[project.scripts]
|
|
42
|
+
envbool = "envbool._cli:main"
|
|
43
|
+
|
|
44
|
+
[build-system]
|
|
45
|
+
requires = ["uv_build>=0.12.0,<0.13.0"]
|
|
46
|
+
build-backend = "uv_build"
|
|
47
|
+
|
|
48
|
+
[dependency-groups]
|
|
49
|
+
dev = [
|
|
50
|
+
"hypothesis>=6.155.5",
|
|
51
|
+
"pre-commit>=4.5.1",
|
|
52
|
+
"pytest>=9.0.3",
|
|
53
|
+
"pytest-cov>=7.1.0",
|
|
54
|
+
"ruff>=0.15.10",
|
|
55
|
+
"ty>=0.0.29",
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
[tool.ruff]
|
|
59
|
+
target-version = "py311"
|
|
60
|
+
line-length = 88
|
|
61
|
+
|
|
62
|
+
[tool.ruff.lint]
|
|
63
|
+
select = ["ALL"]
|
|
64
|
+
ignore = [
|
|
65
|
+
"D203",
|
|
66
|
+
"D213",
|
|
67
|
+
"D100",
|
|
68
|
+
"D104",
|
|
69
|
+
"D107",
|
|
70
|
+
"ANN401",
|
|
71
|
+
"COM812",
|
|
72
|
+
"ISC001",
|
|
73
|
+
"FIX002",
|
|
74
|
+
"TD002",
|
|
75
|
+
"TD003",
|
|
76
|
+
"ERA001",
|
|
77
|
+
"TRY003",
|
|
78
|
+
"EM101",
|
|
79
|
+
"EM102",
|
|
80
|
+
"S101",
|
|
81
|
+
"PLR2004",
|
|
82
|
+
"PLR0913",
|
|
83
|
+
"CPY001",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[tool.ruff.lint.pydocstyle]
|
|
87
|
+
convention = "google"
|
|
88
|
+
|
|
89
|
+
[tool.ruff.lint.per-file-ignores]
|
|
90
|
+
"tests/**/*.py" = [
|
|
91
|
+
"D",
|
|
92
|
+
"ANN",
|
|
93
|
+
"SLF001",
|
|
94
|
+
]
|
|
95
|
+
"src/envbool/_cli.py" = ["T201"]
|
|
96
|
+
|
|
97
|
+
[tool.ty.rules]
|
|
98
|
+
possibly-missing-import = "warn"
|
|
99
|
+
|
|
100
|
+
[tool.pytest.ini_options]
|
|
101
|
+
testpaths = ["tests"]
|
|
102
|
+
addopts = [
|
|
103
|
+
"-ra",
|
|
104
|
+
"--strict-markers",
|
|
105
|
+
"--strict-config",
|
|
106
|
+
"--cov",
|
|
107
|
+
"--cov-fail-under=100",
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
[tool.coverage.run]
|
|
111
|
+
source = ["envbool"]
|
|
112
|
+
branch = true
|
|
113
|
+
|
|
114
|
+
[tool.coverage.report]
|
|
115
|
+
show_missing = true
|
|
116
|
+
skip_empty = true
|
|
117
|
+
exclude_lines = [
|
|
118
|
+
"pragma: no cover",
|
|
119
|
+
"if TYPE_CHECKING:",
|
|
120
|
+
"if __name__ == .__main__.",
|
|
121
|
+
]
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "envbool"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.1"
|
|
4
4
|
description = "A small Python library and CLI tool for coercing environment variables (and arbitrary strings) into boolean values."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "Kyle O'Malley", email = "j.kyle.omalley@gmail.com" }]
|
|
7
7
|
requires-python = ">=3.11"
|
|
8
8
|
license = "MIT"
|
|
9
9
|
keywords = ["environment variables", "boolean", "configuration", "env", "coerce"]
|
|
10
|
-
dependencies = [
|
|
11
|
-
"platformdirs>=4.9.6",
|
|
12
|
-
]
|
|
10
|
+
dependencies = []
|
|
13
11
|
classifiers = [
|
|
14
12
|
"Development Status :: 4 - Beta",
|
|
15
13
|
"Intended Audience :: Developers",
|
|
@@ -29,13 +27,13 @@ classifiers = [
|
|
|
29
27
|
Homepage = "https://github.com/jkomalley/envbool"
|
|
30
28
|
Repository = "https://github.com/jkomalley/envbool"
|
|
31
29
|
Issues = "https://github.com/jkomalley/envbool/issues"
|
|
32
|
-
Changelog = "https://github.com/jkomalley/envbool/
|
|
30
|
+
Changelog = "https://github.com/jkomalley/envbool/blob/main/CHANGELOG.md"
|
|
33
31
|
|
|
34
32
|
[project.scripts]
|
|
35
33
|
envbool = "envbool._cli:main"
|
|
36
34
|
|
|
37
35
|
[build-system]
|
|
38
|
-
requires = ["uv_build>=0.
|
|
36
|
+
requires = ["uv_build>=0.12.0,<0.13.0"]
|
|
39
37
|
build-backend = "uv_build"
|
|
40
38
|
|
|
41
39
|
[dependency-groups]
|
|
@@ -112,6 +110,11 @@ addopts = [
|
|
|
112
110
|
"-ra",
|
|
113
111
|
"--strict-markers",
|
|
114
112
|
"--strict-config",
|
|
113
|
+
# Coverage policy lives here, not in the CI step, so the CI `check` job
|
|
114
|
+
# stays byte-identical across repos. `--cov` bare is enough because
|
|
115
|
+
# [tool.coverage.run] sets source below.
|
|
116
|
+
"--cov",
|
|
117
|
+
"--cov-fail-under=100",
|
|
115
118
|
]
|
|
116
119
|
|
|
117
120
|
# --------------------------------------------------------------------------- #
|
|
@@ -11,26 +11,31 @@ For except clauses, envbool.exceptions is also importable by name:
|
|
|
11
11
|
Available names:
|
|
12
12
|
envbool() -- read an env var and coerce to bool (primary API)
|
|
13
13
|
to_bool() -- coerce an arbitrary string to bool (no os.environ)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
set_defaults() -- set process-level strict/warn/truthy/falsy defaults
|
|
15
|
+
get_defaults() -- inspect the active process-level Defaults
|
|
16
|
+
reset_defaults() -- restore built-in defaults (for test fixtures)
|
|
17
|
+
Defaults -- frozen dataclass returned by get_defaults()
|
|
17
18
|
DEFAULT_TRUTHY -- built-in truthy set (frozenset)
|
|
18
19
|
DEFAULT_FALSY -- built-in falsy set (frozenset)
|
|
19
20
|
EnvBoolError -- base exception for all envbool errors
|
|
20
21
|
InvalidBoolValueError -- raised in strict mode for unrecognized values
|
|
21
22
|
MissingEnvVarError -- raised by envbool(required=True) when a var is unset
|
|
22
|
-
ConfigError -- raised for malformed or unreadable config files
|
|
23
23
|
"""
|
|
24
24
|
# All implementation lives in private underscore-prefixed modules so the public
|
|
25
25
|
# surface can be reshaped without breaking imports. Do not import from _core,
|
|
26
26
|
# _env, _config, _cli, or _defaults directly.
|
|
27
27
|
|
|
28
|
-
from envbool._config import EnvBoolConfig, load_config, reload_config
|
|
29
28
|
from envbool._core import to_bool
|
|
30
|
-
from envbool._defaults import
|
|
29
|
+
from envbool._defaults import (
|
|
30
|
+
DEFAULT_FALSY,
|
|
31
|
+
DEFAULT_TRUTHY,
|
|
32
|
+
Defaults,
|
|
33
|
+
get_defaults,
|
|
34
|
+
reset_defaults,
|
|
35
|
+
set_defaults,
|
|
36
|
+
)
|
|
31
37
|
from envbool._env import envbool
|
|
32
38
|
from envbool.exceptions import (
|
|
33
|
-
ConfigError,
|
|
34
39
|
EnvBoolError,
|
|
35
40
|
InvalidBoolValueError,
|
|
36
41
|
MissingEnvVarError,
|
|
@@ -39,13 +44,13 @@ from envbool.exceptions import (
|
|
|
39
44
|
__all__ = [
|
|
40
45
|
"DEFAULT_FALSY",
|
|
41
46
|
"DEFAULT_TRUTHY",
|
|
42
|
-
"
|
|
43
|
-
"EnvBoolConfig",
|
|
47
|
+
"Defaults",
|
|
44
48
|
"EnvBoolError",
|
|
45
49
|
"InvalidBoolValueError",
|
|
46
50
|
"MissingEnvVarError",
|
|
47
51
|
"envbool",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
52
|
+
"get_defaults",
|
|
53
|
+
"reset_defaults",
|
|
54
|
+
"set_defaults",
|
|
50
55
|
"to_bool",
|
|
51
56
|
]
|