Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions confuse/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,24 @@ def dump(self, full: bool = True, redact: bool = False) -> str:
temp_root.redactions = self.redactions
out_dict = temp_root.flatten(redact=redact)

# `keys()` enumerates the sources in priority order, so keys that
# only appear in a lower-priority source (such as the defaults) are
# listed after every key of the highest-priority source. Restore the
# documented ordering by putting the keys of the default source
# first, in the order they appear there.
default_keys = [
key for source in self.sources if source.default for key in source.keys()
]
if default_keys:
ordered = OrderedDict()
for key in default_keys:
if key in out_dict:
ordered[key] = out_dict[key]
for key, value in out_dict.items():
if key not in ordered:
ordered[key] = value
out_dict = ordered

yaml_out = yaml.dump(
out_dict,
Dumper=yaml_util.Dumper,
Expand Down
11 changes: 11 additions & 0 deletions test/test_dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ def test_dump_sans_defaults(self):
yaml = config.dump(full=False).strip()
assert yaml == "baz: qux"

def test_dump_follows_default_key_order(self):
config = confuse.Configuration("myapp", read=False)
config.add({"foo": "bar", "baz": "qux"})
config.sources[0].default = True
# A higher-priority source that lists the keys in a different order
# and only overrides the second one.
config.set({"baz": "override"})

yaml = config.dump().strip()
assert yaml == "foo: bar\nbaz: override"


class RedactTest(unittest.TestCase):
def test_no_redaction(self):
Expand Down
Loading