conclude 1.0.0__py3-none-any.whl

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.
conclude/__init__.py ADDED
@@ -0,0 +1,189 @@
1
+ """conclude: layered CLI-flag / env-var / config-file / default config
2
+ resolution, with no opinion about what your settings actually are.
3
+
4
+ The name: you write down your settings' *defaults* -- their names,
5
+ their types, their starting values -- and conclude works out
6
+ everything else (env var names, config file keys, CLI flag names, and
7
+ how to cast a raw value from any layer into the right type) from that
8
+ one dict. You supply the premises; conclude draws the conclusion.
9
+
10
+ This package is the arg-env-config-default *mechanism* extracted out of
11
+ an application's config module: given a dict of hardcoded defaults, a
12
+ dict of casters (one per setting, so every layer normalizes the same
13
+ way before merging), and the already-loaded CLI/env/config-file layers,
14
+ ``resolve()`` merges them lowest-priority-first into one plain dict.
15
+ Everything else here exists to *produce* those layers:
16
+
17
+ - :class:`conclude.App` -- the convenience layer: give it your app's
18
+ name and its defaults dict, and it infers env var names, casters,
19
+ and (via ``add_arguments``/``build_arg_parser``) CLI flag names, all
20
+ from that one dict. This is the one most applications want; the
21
+ rest of this list is what it's built from, for anyone who wants the
22
+ pieces separately. It also has ``format_invocation()``, the inverse
23
+ direction: given a resolved settings dict, render the standalone
24
+ command line that reproduces it -- handy for debugging a confusing
25
+ resolved setup, or documenting one. Its ``format_env()``/
26
+ ``format_toml()``/``format_cli()`` render every setting's name in
27
+ that layer next to its default -- a ready-to-paste ``.env``/config-file
28
+ template or CLI reference, generated from the same ``defaults``. Any of
29
+ its three file-based
30
+ sources (``dotenv_path``/``config_home_path``/``config_cwd_path``)
31
+ can be set to ``None`` to disable that source outright (plus an
32
+ opt-in, lowest-priority system-wide file, ``config_system_path=AUTO``
33
+ for ``/etc/<name>/config.toml``, and an opt-in developer file above
34
+ the environment, ``pyproject_path=AUTO``; the project file's
35
+ ``.config.*.toml`` siblings have their own ``config_cwd_aux_pattern``
36
+ knob), and
37
+ ``describe_sources()`` renders which ones are active/disabled --
38
+ meant for your program's own ``--help`` text, since that's a fact
39
+ about the program, not about any one run's resolved values.
40
+ - :mod:`conclude.templates` -- the value-rendering helpers behind
41
+ ``App.format_env()``/``format_toml()``/``format_cli()``.
42
+ - :mod:`conclude.guard` -- the gitignore guard shared by the developer
43
+ file and (optionally) a ``.env`` file: exists, inside a git working
44
+ tree, and ignored by it.
45
+ - :mod:`conclude.developer` -- the opt-in developer config layer
46
+ (``defaults < ... < env < developer < CLI``): a private,
47
+ gitignored, project-local file, named by ``pyproject.toml``'s
48
+ ``tool.conclude.developer.config``, that beats ambient environment
49
+ variables; ``DeveloperStatus`` says which of four states it is in.
50
+ - :func:`conclude.opt` -- the default to write for an optional
51
+ setting (one that starts out ``None``) so caster/formatter inference
52
+ still knows its real type, e.g. ``opt(str)``.
53
+ - :mod:`conclude.naming` -- ``cli_flag_name()``/``env_var_name()``/
54
+ ``config_key_name()``, deriving each layer's conventional name for a
55
+ setting from its Python key alone.
56
+ - :mod:`conclude.infer` -- ``infer_caster()``/``infer_casters()``,
57
+ picking a caster from a default's type (or an ``opt()``-wrapped
58
+ type), and ``effective_defaults()`` to unwrap ``opt()`` placeholders.
59
+ ``conclude.Caster`` names the shape a caster/override is expected to
60
+ have: ``Callable[[Any], Any]``.
61
+ - :mod:`conclude.formatters` -- ``infer_formatter()``/
62
+ ``infer_formatters()``, the inverse of :mod:`conclude.infer`: picking
63
+ the CLI-token rendering for a resolved value from its type, for
64
+ ``App.format_invocation()``. ``conclude.Formatter`` names that shape:
65
+ ``Callable[[Any], str | None]``.
66
+ - :mod:`conclude.casters` -- the small, reusable value casters
67
+ (bool, int-or-None, float-or-None, positive int, str-or-None,
68
+ comma-separated list, backslash-escaped string) that inference picks
69
+ from, and that also work fine written out by hand for a setting that
70
+ needs an explicit override. ``decode_backslash_escapes()`` is the
71
+ narrow ``\n``/``\t``/``\r``/``\\``/``\"`` decoder
72
+ ``cast_escaped_str`` (and ``.env`` double-quoted values) use under
73
+ the hood -- non-ASCII text always passes through unchanged.
74
+ - :mod:`conclude.env` -- ``load_env()`` reads a dict of
75
+ ``{setting_name: ENV_VAR_NAME}`` out of the environment, optionally
76
+ falling back to a ``.env`` file (``load_dotenv()``) for anything not
77
+ actually set there.
78
+ - :mod:`conclude.files` -- TOML config file loading, with support for
79
+ a two-level ``[PARENT]``/``[PARENT.CHILD]`` table selection, a
80
+ project-local file that overrides a user-global one, sibling
81
+ "auxiliary" files picked up automatically, and resolving which
82
+ table a bare positional shorthand argument (a "deck" name, a
83
+ "profile" name, whatever your app calls it) maps to by peeking at
84
+ the config files themselves.
85
+ - :mod:`conclude.tomlwrite` -- ``toml_string()``/``toml_key()`` for
86
+ generating ready-to-paste TOML snippets (e.g. for a
87
+ "print me a config entry for what I just set up" flag).
88
+ - :mod:`conclude.paths` -- the conventional
89
+ ``~/.config/<app_name>/config.toml`` user path and
90
+ ``/etc/<app_name>/config.toml`` system path for a given app name.
91
+ - :func:`conclude.resolve` -- the merge itself, for anyone assembling
92
+ the CLI/env/config-file layers by hand instead of through ``App``.
93
+
94
+ What stays in your own application: your defaults dict (that's the
95
+ whole point), and anything inference genuinely can't guess for a
96
+ particular setting -- a caster with its own error-message wording, a
97
+ hand-written ``--help`` string, or CLI/config behavior beyond "one
98
+ flag per setting" (a positional shorthand argument, say). Each of
99
+ those is a small, targeted override; you don't lose inference for
100
+ every other setting to get one.
101
+ """
102
+
103
+ from conclude.app import AUTO, App
104
+ from conclude.casters import (
105
+ cast_bool,
106
+ cast_comma_list,
107
+ cast_escaped_str,
108
+ cast_float_or_none,
109
+ cast_int_or_none,
110
+ cast_positive_int,
111
+ cast_str_or_none,
112
+ decode_backslash_escapes,
113
+ )
114
+ from conclude.developer import DeveloperState, DeveloperStatus, developer_status
115
+ from conclude.env import DotenvState, DotenvStatus, dotenv_status, load_dotenv, load_env
116
+ from conclude.files import (
117
+ ConfigFileError,
118
+ cwd_aux_config_paths,
119
+ load_config_file,
120
+ load_config_files,
121
+ load_raw_toml,
122
+ parse_config_table,
123
+ resolve_config_table,
124
+ table_exists,
125
+ )
126
+ from conclude.formatters import (
127
+ Formatter,
128
+ format_bool,
129
+ format_list,
130
+ format_scalar,
131
+ infer_formatter,
132
+ infer_formatters,
133
+ )
134
+ from conclude.infer import Caster, Opt, effective_defaults, infer_caster, infer_casters, opt
135
+ from conclude.merge import resolve
136
+ from conclude.naming import cli_flag_name, config_key_name, env_var_name
137
+ from conclude.paths import default_config_home_path, default_config_system_path
138
+ from conclude.tomlwrite import toml_key, toml_string
139
+
140
+ __version__ = "1.0.0"
141
+
142
+ __all__ = [
143
+ "App",
144
+ "AUTO",
145
+ "Opt",
146
+ "opt",
147
+ "Caster",
148
+ "Formatter",
149
+ "effective_defaults",
150
+ "infer_caster",
151
+ "infer_casters",
152
+ "format_bool",
153
+ "format_list",
154
+ "format_scalar",
155
+ "infer_formatter",
156
+ "infer_formatters",
157
+ "cli_flag_name",
158
+ "config_key_name",
159
+ "env_var_name",
160
+ "cast_bool",
161
+ "cast_comma_list",
162
+ "cast_escaped_str",
163
+ "cast_float_or_none",
164
+ "cast_int_or_none",
165
+ "cast_positive_int",
166
+ "cast_str_or_none",
167
+ "decode_backslash_escapes",
168
+ "DotenvState",
169
+ "DotenvStatus",
170
+ "dotenv_status",
171
+ "DeveloperState",
172
+ "DeveloperStatus",
173
+ "developer_status",
174
+ "load_env",
175
+ "load_dotenv",
176
+ "ConfigFileError",
177
+ "cwd_aux_config_paths",
178
+ "load_config_file",
179
+ "load_config_files",
180
+ "load_raw_toml",
181
+ "parse_config_table",
182
+ "resolve_config_table",
183
+ "table_exists",
184
+ "resolve",
185
+ "default_config_home_path",
186
+ "default_config_system_path",
187
+ "toml_key",
188
+ "toml_string",
189
+ ]