python-poetry/tomlkit

Writing nested AOTs produces redundant parent AOT

Closed this issue · 2 comments

I can parse a document with nested array-of-tables just fine. Trying to write one, however, is difficult and actually seems impossible.

Using this code...

import tomlkit as toml

data = {
    # Array of length one for brevity, but you can easily imagine one of greater length.
    "groups": [
        {
            "name": "Grp A",
            "categories": [
                {
                    "name": "Cat W",
                    "value": 1,
                },
                {
                    "name": "Cat X",
                    "value": 2,
                },
            ],
        },
    ],
}

ts: str = ""

doc = toml.document()

for g in data["groups"]:
    group_aot = toml.aot()
    group_aot.append({"name": g["name"]})

    for c in g["categories"]:
        cat_aot = toml.aot()
        cat_aot.append({"name": c["name"], "value": c["value"]})
        group_aot.append({"categories": cat_aot})

    doc.append("groups", group_aot)

print(toml.dumps(doc))

I get the following output:

[[groups]]
name = "Grp A"

[[groups]]
[[groups.categories]]
name = "Cat W"
value = 1

[[groups]]
[[groups.categories]]
name = "Cat X"
value = 2

I'd like to not have the redundant [[groups]] above every [[groups.categories]]. Am I missing an API usage pattern, or is this currently impossible?

It's as simple as a single line of code:

doc = tomlkit.dumps(data)

And the correct code to generate this is:

import tomlkit as toml


data = {
    # Array of length one for brevity, but you can easily imagine one of greater length.
    "groups": [
        {
            "name": "Grp A",
            "categories": [
                {
                    "name": "Cat W",
                    "value": 1,
                },
                {
                    "name": "Cat X",
                    "value": 2,
                },
            ],
        },
    ],
}

ts: str = ""

doc = toml.document()
group_aot = toml.aot()

for g in data["groups"]:
    group_table = toml.table()
    group_table.append("name", g["name"])

    cat_aot = toml.aot()
    for c in g["categories"]:
        cat_aot.append(c)
    group_table.append("categories", cat_aot)
    group_aot.append(group_table)
doc.append("groups", group_aot)

print(toml.dumps(doc))

You're probably getting dizzy in nested loops.

Yes, declaring the aots outside their respective loops and using an extra table for each group is what I was missing. Gtk I can do it all in one line too. Thanks @frostming !