Skip to content

Commit 99a5ffb

Browse files
Document usethis_config global state management (#1100)
* Initial plan * Add documentation for usethis_config global state Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com> * Editorialize `CONTRIBUTING.md` section regarding `usethis_config` --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com> Co-authored-by: Nathan McDougall <nathan.j.mcdougall@gmail.com>
1 parent 02917af commit 99a5ffb

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

.github/copilot-instructions.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,30 @@ src/usethis/
127127
- `_pipeweld` is completely independent
128128
- See `[[tool.importlinter.contracts]]` in pyproject.toml for full layer definitions
129129

130+
### Global Configuration State (`usethis_config`)
131+
132+
**CRITICAL:** The `usethis._config.usethis_config` object manages global application state. This is used to avoid pass-through variables that would otherwise need to be threaded through many layers of function calls.
133+
134+
**When to use global state:**
135+
-**DO** use `usethis_config` for settings that affect application behavior across many different commands
136+
-**DO** use it for application-wide concerns: output verbosity (`quiet`, `alert_only`, `instruct_only`), network access (`offline`), dependency installation (`frozen`), build backend (`backend`), etc.
137+
-**DO NOT** add new global state for command-specific behavior that only affects a single CLI command
138+
-**DO NOT** use it for passing data between functions (use function parameters instead)
139+
140+
**Requirements for adding new global state:**
141+
1. There must be a very good reason - the default should be to use function parameters
142+
2. The state must be useful across the whole application, not just one or two commands
143+
3. The purpose must be to control application behavior (e.g., how output is displayed, whether network is allowed), not the specific business logic of a command
144+
4. Document the new state clearly in the `UsethisConfig` docstring
145+
146+
**How it works:**
147+
- `usethis_config.set()` is a context manager that temporarily overrides settings
148+
- CLI commands use it to apply command-line flags: `with usethis_config.set(offline=offline, quiet=quiet):`
149+
- Internal functions access current config: `if usethis_config.quiet: return`
150+
- Settings are automatically restored when the context manager exits
151+
152+
See CONTRIBUTING.md Architecture section for detailed documentation and examples.
153+
130154
### Configuration Files
131155
- `pyproject.toml` - Main project config, dependencies, tool configurations (Ruff, pytest, coverage, import-linter)
132156
- `uv.lock` - Lock file (committed to repo)

CONTRIBUTING.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ It is recommended that you use signed commits, although this is not a requiremen
7474

7575
This project uses [Import Linter](https://import-linter.readthedocs.io/en/stable/) to enforce a software architecture. Refer to the `[[tool.importlinter.contracts]]` sections in `pyproject.toml` to understand the structure of the project.
7676

77+
### Global Configuration State
78+
79+
The `usethis._config.usethis_config` object manages global application state that affects behavior across the entire application. This design avoids the need for pass-through variables that would otherwise need to be threaded through many layers of function calls. It provides a context manager, `usethis_config.set()`, which temporarily overrides global settings:
80+
81+
```python
82+
# Temporarily suppress all output except warnings and errors
83+
with usethis_config.set(alert_only=True):
84+
# Code here runs with modified config
85+
do_something()
86+
# Original settings are automatically restored
87+
```
88+
7789
## Python Version Support
7890

7991
This project supports all versions of Python through until end of life. The development environment uses the oldest supported version, which is given in the `.python-version` file. The GitHub Actions pipeline tests all supported versions.

0 commit comments

Comments
 (0)