Skip to content

feat: warn on duplicate keys in the env cascade - #81

Open
rcbevans wants to merge 1 commit into
mainfrom
fix/duplicate-key-warning
Open

rcbevans wants to merge 1 commit into
mainfrom
fix/duplicate-key-warning

Conversation

@rcbevans

Copy link
Copy Markdown
Contributor

Closes #80.

What

A key defined more than once in the .env cascade now logs a WARNING at load time, naming the file, the key, and both values:

  • within one file: Duplicate key 'A' in /path/.env: the later value wins. Remove the stale occurrence.
  • across the cascade: Key 'SHARED' redefined in /path/.env.dev: 'base' (earlier file) is overridden by 'dev-specific' (this file).

The merge semantics are unchanged (last-wins, python-dotenv's own dict behavior) — this only makes the flip visible instead of silent.

How

Within-file detection tokenizes with python-dotenv's own parse_stream (one binding per occurrence, quote- and multiline-aware — a KEY= line inside a quoted multi-line value cannot false-positive), imported lazily inside the detector under a guarded import: dotenv.parser is not public API, so a future python-dotenv may break it — the worst case is that the warning degrades to silence, never an import-time break. TestNoDotenvInternals documents the sanctioned exception and still fails on any module-level dotenv.* import.

Tests

tests/test_duplicate_keys.py (5): within-file warn + last-wins unchanged; clean files never warn; quoted multi-line values do not false-positive (and the real duplicate is the only one named); cross-cascade redefinition names both values; three occurrences warn once per key.

Full suite: 1,433 passed; ruff clean.

A key defined twice (within one file, or redefined by a later cascade
file) is almost always an editing mistake, and the merge is dict-based:
the later value silently wins. Nothing crashed, nothing warned, and the
failure mode is a silently flipped default discovered in production.

The merge semantics are unchanged (last-wins, python-dotenv's own
dict behavior); each duplicate now logs a WARNING naming the file, the
key, and both values at load time.

Within-file detection tokenizes with python-dotenv's own parse_stream
(quote- and multiline-aware; a KEY= line inside a quoted multi-line
value cannot false-positive), imported lazily inside the detector under
a guarded import: dotenv.parser is not public API, so a future
python-dotenv may break it - the worst case is that the warning
degrades to silence, never an import-time break (the hermetic-loading
pin documents the sanctioned exception).

Fixes #80

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate keys in .env files are silently collapsed (last one wins) — bit me for real

1 participant