Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve inline dict inside an array #396

Open
hniksic opened this issue Apr 23, 2022 · 3 comments
Open

Preserve inline dict inside an array #396

hniksic opened this issue Apr 23, 2022 · 3 comments

Comments

@hniksic
Copy link

hniksic commented Apr 23, 2022

I have a TOML whose section contains an array of inline dicts:

[section]
list-key = [
    { path = "foo.jsonl", id_key = "id" },
    { path = "bar.jsonl", id_key = "id" },
    # ...
]

After running it through toml using something like:

t = toml.load(open('test.toml'))
toml.dump(t, sys.stdout, encoder=toml.TomlEncoder(preserve=True))

the file gets transformed into:

[section]
[[section.list-key]]
path = "foo.jsonl"
id_key = "id"

[[section.list-key]]
path = "bar.jsonl"
id_key = "id"

Given the above snippet the output doesn't look that bad, but in my actual example the inner dicts have 7 keys each, and there are many dicts in the list, so the updating the file causes an explosion of line count, making the output wordier and less readable than the original.

Curiously, the decoder seems to be doing the right thing, since the type of t['section']['list-key'][0] is reported as <class 'toml.decoder.TomlDecoder.get_empty_inline_table.<locals>.DynamicInlineTableDict'>. I'd therefore expect the encoder to preserve the inline dicts, but I can't get it to do so.

Is there any way to preserve inline dicts inside an array? Note that this is similar to #383, but the difference is that there the dict is inside a dict, and here it's inside an array, and the workarounds presented there don't make a difference for me.

@goodboy
Copy link

goodboy commented Jun 17, 2022

Given the above snippet the output doesn't look that bad, but in my actual example the inner dicts have 7 keys each, and there are many dicts in the list, so the updating the file causes an explosion of line count, making the output wordier and less readable than the original.

This is also the exact problem I am having; would prefer also to have the ability to write inline tables from the encoder without having to read in / detect them in the first place. I think this makes sense for content that you want to compact in certain ways and not have tons of LOC.

Going to try the #383 solution and report back 🏄🏼

@goodboy
Copy link

goodboy commented Jun 19, 2022

fwiw this encoder override method seems to mostly work, but may require an additional override of .dump_sections():

    def dump_list(self, v):
        '''
        Dump an inline list with a newline after every element and
        with consideration for denoted inline table types.

        '''
        retval = "[\n"
        for u in v:
            if isinstance(u, toml.decoder.InlineTableDict):
                out = self.dump_inline_table(u)
            else:
                out = str(self.dump_value(u))

            retval += " " + out + "," + "\n"
        retval += "]"
        return retval

@goodboy
Copy link

goodboy commented Apr 26, 2023

Fwiw, we've switched to the much much more flexible tomlkit lib which is built ground up to be style preserving and has native support for inline tables using :

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

No branches or pull requests

2 participants