Skip to content

item() reorders keys (dict-valued before scalar) even with the default sort_keys=False #546

Description

@pramodavansaber

Summary

When tomlkit.items.item() builds a value from a Python list of dicts, its sort key has a misplaced parenthesis:
key=lambda i: (isinstance(i[1], dict), i[0] if _sort_keys else 1). The if _sort_keys else 1 guards only i[0], so the isinstance(i[1], dict) term stays active — dict-valued keys are forced after scalar-valued keys even when sort_keys=False. The sibling top-level branch guards the whole tuple correctly: (isinstance(i[1], dict), i[0]) if _sort_keys else 1.

Reproduction

from tomlkit.items import item
print(item([{'a': {'x': 1}, 'b': 2}]).as_string())
# b = 2
#
# [a]
# x = 1

Input key order is a, b, but b is emitted before the [a] table.

Expected

With the default sort_keys=False, key order is preserved: the [a] table, then b = 2.

Actual

b = 2 is emitted before [a] — keys silently reordered.

Fix sketch

Guard the whole sort tuple with _sort_keys, matching the top-level dict branch.

Environment

tomlkit 0.15.0 (master @ 43668dd), Python 3.12.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions