Skip to content

Pass along _parent and _sort_keys to custom encoders #429

@mikael-s-persson

Description

@mikael-s-persson

Custom encoders provide a way to have custom objects in the "tree" of stuff that gets rendered to a toml file by allowing the user to provide the item-generation code (aka encoder). The actual recursive tree-traversal encoder used by tomlkit carries through the arguments: _parent (item within which the created item would get inserted) and _sort_keys (just a user option). When encoding only simple values (aka a tree leaf), those parameters don't matter, but in order to write a custom encoder for a dict-like, list-like or tuple-like custom object, those are relevant.

Context: I was writing a sort of "decorated tree" of config values, specifically to keep track of file/line-number of where a particular config value was set, to later render those source locations as comments in the toml config file, next to each config value. I ended up writing this horrible custom encoder:

def traced_item_encoder(traced_item):
    if not isinstance(traced_item, TracedItem):
        raise tomlkit.ConvertError("Expecting a TracedItem")
    # We use a pretty crazy hack here because tomlkit doesn't forward the _parent and _sort_keys
    # arguments to the custom encoders, but they are needed to correctly handle dict and list values.
    # So, we walk up the stack and pick them out ourselves.
    it = tomlkit.item(
        traced_item.raw_value,
        _parent=inspect.currentframe().f_back.f_locals["_parent"],
        _sort_keys=inspect.currentframe().f_back.f_locals["_sort_keys"],
    )
    if traced_item.origin:
        it.comment("ORIGIN: " + traced_item.origin)
    return it

I'm guessing the solution would be to pass a **kwargs down, since I would assume most custom encoders end up making a call to tomlkit.item eventually.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions