Skip to content

Commit 435bb11

Browse files
committed
docs: correct the silencing guidance - PYTHONWARNINGS cannot name the category
Interpreter warning filters (-W / PYTHONWARNINGS) are parsed before site-packages is importable, so a third-party category never resolves and the filter is silently dropped. And since entrypoint() runs from sitecustomize at startup, an in-process filterwarnings() call only affects a later manual entrypoint() call, not the startup pass. Rewrite docs/configuration.md "Silencing warnings" into three honest sections: from Python (filterwarnings / pytest config), at startup (only ignore::UserWarning works, broadly), and better - remove the cause (empty .env or AUTOREAD_DOTENV_PATH). Adjust the warnings.py and entrypoint() docstrings and the changelog entry to match.
1 parent 3c24238 commit 435bb11

4 files changed

Lines changed: 54 additions & 30 deletions

File tree

docs/changes.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ All notable changes to this project will be documented in this file.
77
- Emit every runtime warning under a dedicated `AutoreadDotenvWarning` category (a
88
`UserWarning` subclass) instead of a bare `UserWarning`. It lives in
99
`autoread_dotenv.warnings` and is re-exported as `autoread_dotenv.AutoreadDotenvWarning`
10-
(added to `__all__`, alongside `LoadStatus`). Callers can now silence just this package --
11-
e.g. `PYTHONWARNINGS=ignore::autoread_dotenv.AutoreadDotenvWarning` -- without muting
12-
unrelated `UserWarning`s. Documented under "Silencing warnings" in `docs/configuration.md`.
13-
Also fixes the module-reload order in `tests/conftest.py` so reloaded modules re-bind to the
14-
fresh category.
10+
(added to `__all__`, alongside `LoadStatus`). Programmatic callers and test suites can now
11+
filter just this package with `warnings.filterwarnings("ignore",
12+
category=AutoreadDotenvWarning)` or pytest's `filterwarnings` config, without muting
13+
unrelated `UserWarning`s. Note that `PYTHONWARNINGS` / `-W` cannot reference the category
14+
(warning filters are parsed before `site-packages` is importable); the new "Silencing
15+
warnings" section of `docs/configuration.md` covers the startup case. Also fixes the
16+
module-reload order in `tests/conftest.py` so reloaded modules re-bind to the fresh
17+
category.
1518

1619
- Migrate the documentation from Sphinx to MkDocs + Material for MkDocs. The API
1720
reference is now generated by `mkdocstrings` (Python handler) instead of

docs/configuration.md

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,37 +58,56 @@ export AUTOREAD_ENFORCE_DOTENV=0
5858
`autoread-dotenv` never raises for a configuration problem - it emits a warning and records
5959
the reason in [`last_load_status`](reference/status.md). Every one of those warnings uses the
6060
category [`AutoreadDotenvWarning`](reference/warnings.md) (a subclass of `UserWarning`),
61-
re-exported as `autoread_dotenv.AutoreadDotenvWarning`, so you can suppress *only* this package
62-
without muting unrelated `UserWarning`s from the rest of your app:
61+
re-exported as `autoread_dotenv.AutoreadDotenvWarning`.
6362

64-
```bash
65-
# environment (before the interpreter starts, like the variables above)
66-
export PYTHONWARNINGS="ignore::autoread_dotenv.AutoreadDotenvWarning"
63+
### From Python (tests, programmatic callers)
6764

68-
# one-off invocation
69-
python -W "ignore::autoread_dotenv.AutoreadDotenvWarning" -m myapp
70-
```
65+
Filter the category directly:
7166

7267
```python
73-
# from code, before autoread_dotenv.entrypoint() runs
7468
import warnings
7569
from autoread_dotenv import AutoreadDotenvWarning
7670

7771
warnings.filterwarnings("ignore", category=AutoreadDotenvWarning)
7872
```
7973

8074
```toml
81-
# pytest
75+
# pytest resolves the category itself, so the dotted path works here
8276
[tool.pytest.ini_options]
83-
filterwarnings = ["ignore::autoread_dotenv.AutoreadDotenvWarning"]
77+
filterwarnings = ["ignore::autoread_dotenv.warnings.AutoreadDotenvWarning"]
78+
```
79+
80+
Note the timing: `entrypoint()` runs from `sitecustomize` at interpreter startup, *before* any
81+
of your code. An in-process `filterwarnings()` call therefore only affects a later, manual
82+
`entrypoint()` invocation - it cannot retroactively silence the startup pass. Use the options
83+
in the next section for that.
84+
85+
### At startup (`PYTHONWARNINGS` / `-W`)
86+
87+
`PYTHONWARNINGS` and `-W` **cannot** name `AutoreadDotenvWarning`. The interpreter parses
88+
warning filters before `site` puts `site-packages` on `sys.path`, so a third-party category
89+
cannot be imported yet and the whole filter is silently dropped
90+
(`Invalid -W option ignored: invalid module name: 'autoread_dotenv'`). Only built-in
91+
categories resolve there:
92+
93+
```bash
94+
# broad - silences every UserWarning in the process, not just ours
95+
export PYTHONWARNINGS="ignore::UserWarning"
8496
```
8597

86-
The fully-qualified `autoread_dotenv.warnings.AutoreadDotenvWarning` works everywhere too.
98+
### Better: remove the cause
99+
100+
The most common warning is the missing-`.env` notice. Rather than muting it, point the loader
101+
at a file that exists - an empty `.env` is enough - or set `AUTOREAD_DOTENV_PATH`:
102+
103+
```bash
104+
touch "$PWD/.env"
105+
# or
106+
export AUTOREAD_DOTENV_PATH=/etc/myapp/production.env
107+
```
87108

88-
This is all-or-nothing: it silences the missing-`.env` notice together with the genuine
89-
misconfiguration warnings (`python-dotenv` not installed, an unreadable `.env`, a typo'd
90-
boolean). Prefer narrowing by message with `warnings.filterwarnings(..., message=...)` if you
91-
only want to hide one of them.
109+
The remaining warnings (`python-dotenv` not installed, an unreadable `.env`, a typo'd boolean)
110+
signal genuine misconfiguration and are worth leaving on.
92111

93112
## Setting variables outside `.env`
94113

src/autoread_dotenv/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ def entrypoint() -> LoadStatus:
6868
succeeded. A configuration problem is warned about, never raised - this runs on
6969
every interpreter startup. Every such warning uses the
7070
[`AutoreadDotenvWarning`][autoread_dotenv.AutoreadDotenvWarning] category (re-exported
71-
here from `autoread_dotenv.warnings`), so it can be silenced in isolation - see
72-
`docs/configuration.md`.
71+
here from `autoread_dotenv.warnings`); see the "Silencing warnings" section of
72+
`docs/configuration.md` for how to filter it (and why `PYTHONWARNINGS` cannot).
7373
"""
7474
global last_load_status # noqa: PLW0603
7575

src/autoread_dotenv/warnings.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ class AutoreadDotenvWarning(UserWarning):
1111
"""Category for every runtime warning `autoread-dotenv` emits.
1212
1313
A dedicated subclass of `UserWarning` lets callers silence *only* this package
14-
without also muting unrelated `UserWarning`s from the rest of their app, using
15-
the standard mechanisms - e.g.::
16-
17-
PYTHONWARNINGS=ignore::autoread_dotenv.AutoreadDotenvWarning
18-
19-
or `warnings.filterwarnings("ignore", category=AutoreadDotenvWarning)`, or
20-
pytest's `filterwarnings` marker. Re-exported as `autoread_dotenv.AutoreadDotenvWarning`.
14+
without also muting unrelated `UserWarning`s, via
15+
`warnings.filterwarnings("ignore", category=AutoreadDotenvWarning)` or pytest's
16+
`filterwarnings` config. Re-exported as `autoread_dotenv.AutoreadDotenvWarning`.
17+
18+
Note: `PYTHONWARNINGS` / `-W` cannot reference this category - the interpreter
19+
parses those filters before `site-packages` is importable, so only built-in
20+
categories resolve there. And because `entrypoint()` runs from `sitecustomize`
21+
at startup, an in-process filter only affects a later manual `entrypoint()` call,
22+
not the startup pass. See `docs/configuration.md`.
2123
"""
2224

2325

0 commit comments

Comments
 (0)