Skip to content

Substitute ${name:-default} when the variable is set but empty (POSIX) - #684

Open
ckarnell wants to merge 1 commit into
theskumar:mainfrom
ckarnell:fix/posix-default-on-empty-value
Open

Substitute ${name:-default} when the variable is set but empty (POSIX)#684
ckarnell wants to merge 1 commit into
theskumar:mainfrom
ckarnell:fix/posix-default-on-empty-value

Conversation

@ckarnell

Copy link
Copy Markdown

The README says interpolation follows POSIX variable expansion. ${name:-word} in POSIX substitutes word when name is unset or null, and this only handles unset:

result = env.get(self.name, default)

env.get falls back only when the key is absent, so a variable that exists and is empty returns empty.

.env
  EMPTY=
  GREETING=${EMPTY:-fallback}

dotenv_values  ->  GREETING = ''
sh             ->  fallback

The unset case and the set-to-a-value case both already match, so this is the one branch that doesn't.

The change resolves the name first and falls back to the default when the result is empty, which leaves ${b} with no default alone and keeps ${b:-} empty.

Four cases added to the test_dotenv_values_string_io table. Two fail on main, the empty-with-a-default ones. The other two pin ${b} and ${b:-} on an empty value, which behave the same before and after. Tests go from 226 to 230 passing, with the same 12 pre-existing test_cli.py failures either way. Those are FileNotFoundError on subprocess spawning in my environment, not this path.

This changes behaviour. Anyone who wrote ${VAR:-default} and relied on an empty VAR staying empty gets the default instead now. That's what POSIX and the README both describe, but it's a change, so it's your call whether it belongs in a minor release or wants a note.

The README documents POSIX variable expansion, where ${name:-word} substitutes when name is unset OR null. resolve() used env.get(name, default), which falls back only when the key is absent, so a variable that exists and is empty returned empty. Resolve the name first and fall back when the result is empty. ${name} with no default and ${name:-} on an empty value are unchanged.
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.

1 participant