Skip to content

Make Section.Key stop adding missing keys - #429

Merged
unknwon merged 2 commits into
v2from
v2-key-read-only
Nov 11, 2026
Merged

unknwon merged 2 commits into
v2from
v2-key-read-only

Conversation

@unknwon

@unknwon unknwon commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

Section.Key no longer adds a key when the section has none. In v1 (and v2 so far), sec.Key("PORT").MustInt(3000) added an empty PORT key, so HasKey, Keys and Write saw it after a mere read.

Behavior

  • For a missing name, Key returns a key that reads as empty and isn't in the section.
  • SetValue and SetComment add it, and so do AddShadow and AddNestedValue when the file allows shadows or nested values, so sec.Key(name).SetValue(v) works as before.
  • Until it's added, reads and changes through it follow any key of that name the section gains, e.g., from NewKey, Append, Reload or another Key(name) that was set. Two keys returned for one missing name stay in step.
  • Key("") still returns a key that is never added.

Why

  • Reading no longer changes what is written. This matches Must*, which already stopped storing its default.
  • Reading a key from a raw section no longer makes Write fail.

Cost

Key.Value on a lock-free file takes about 0.2 ns more (2.03 → 2.26 ns) for the missing-key check. Other key benchmarks are within noise.

Tests

  • TestSection_Key gains five subtests: reading doesn't add, each change adds, a missing key follows the key its section gains, it expands as that key, and an empty name is never added. The first fails on the old code.
  • The migration guide has a new section for the change.

Section.Key returns a key that reads as empty for a name the section
doesn't have, and SetValue, SetComment, AddShadow or AddNestedValue adds
it. Until then, reads and changes through it follow any key of that name
the section gains, so two such keys for one name stay in step.

Reading a missing key no longer writes to the file, so HasKey, Keys and
Write don't see it, a raw section read for a key stays writable, and
concurrent reads are safe with Locking(false).
A missing key returned by Section.Key expanded its values with itself,
so a reference to its own name, once the section gained the key, was
expanded twice.

Also narrow the docs: the migration guide no longer claims concurrent
reads are safe with Locking(false), which Section still breaks by adding
missing sections. AddShadow and AddNestedValue add a key only when the
file allows them, and a missing key isn't added once its section gains
a key of its name.
@unknwon
unknwon merged commit 8c6f025 into v2 Nov 11, 2026
7 checks passed
@unknwon
unknwon deleted the v2-key-read-only branch November 11, 2026 15:51
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