Code Monkey home page Code Monkey logo

tomli-w's Introduction

Build Status codecov.io PyPI version

Tomli-W

A lil' TOML writer

Table of Contents generated with mdformat-toc

Intro

Tomli-W is a Python library for writing TOML. It is a write-only counterpart to Tomli, which is a read-only TOML parser. Tomli-W is fully compatible with TOML v1.0.0.

Installation

pip install tomli-w

Usage

Write to string

import tomli_w

doc = {"table": {"nested": {}, "val3": 3}, "val2": 2, "val1": 1}
expected_toml = """\
val2 = 2
val1 = 1

[table]
val3 = 3

[table.nested]
"""
assert tomli_w.dumps(doc) == expected_toml

Write to file

import tomli_w

doc = {"one": 1, "two": 2, "pi": 3}
with open("path_to_file/conf.toml", "wb") as f:
    tomli_w.dump(doc, f)

FAQ

Does Tomli-W sort the document?

No, but it respects sort order of the input data, so one could sort the content of the dict (recursively) before calling tomli_w.dumps.

Does Tomli-W support writing documents with comments or custom whitespace?

No.

Why does Tomli-W not write a multi-line string if the string value contains newlines?

This default was chosen to achieve lossless parse/write round-trips.

TOML strings can contain newlines where exact bytes matter, e.g.

s = "here's a newline\r\n"

TOML strings also can contain newlines where exact byte representation is not relevant, e.g.

s = """here's a newline
"""

A parse/write round-trip that converts the former example to the latter does not preserve the original newline byte sequence. This is why Tomli-W avoids writing multi-line strings.

A keyword argument is provided for users who do not need newline bytes to be preserved:

import tomli_w

doc = {"s": "here's a newline\r\n"}
expected_toml = '''\
s = """
here's a newline
"""
'''
assert tomli_w.dumps(doc, multiline_strings=True) == expected_toml

Is Tomli-W output guaranteed to be valid TOML?

No. If there's a chance that your input data is bad and you need output validation, parse the output string once with tomli.loads. If the parse is successful (does not raise tomli.TOMLDecodeError) then the string is valid TOML.

tomli-w's People

Contributors

abravalheri avatar hukkin avatar pre-commit-ci[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

tomli-w's Issues

Empty values (handling None type)

Toml files can be written without values example:

user="[email protected]"
password=

This empty values could be translated to/from None. So I would expect something like:

import tomli_w

doc = {"table": {"nested": {}, "val3": 3}, "val2": 2, "val1": None}
expected_toml = """\
val2 = 2
val1 =

[table]
val3 = 3

[table.nested]
"""
assert tomli_w.dumps(doc) == expected_toml

to work, but it's not the case.

Would it make sense to add `set` to `ARRAY_TYPES`?

What do you think? For example people might have a list and then cast it as a set to remove duplicates.

tomli_w/_writer.py

ARRAY_TYPES = (list, set, tuple)

tests/test_types.py

def test_set():
    obj = {"test-set": {1, 2, 3}}
    assert (
        tomli_w.dumps(obj)
        == """\
test-set = [
    1,
    2,
    3,
]
"""
    )

TypeError: Object of type <class 'NoneType'> is not TOML serializable

Dear Taneli,

thanks a stack for conceiving and maintaining this excellent library. We just wanted to let you know about an issue we just discovered when serializing NoneType values [1]. We are aware that TOML does not know about any kinds of NULL values (toml-lang/toml#921).

Differently than #34, this issue is merely a proposal to handle NoneType values gracefully by just ignoring them on serialization. The toml package does just that [2]. We have exercised the situation with all of toml, tomlkit, and tomli-w on behalf of a unit test at [3] and also reported the same issue to the author of tomlkit at python-poetry/tomlkit#240.

With kind regards,
Andreas.

[1] isarengineering/SecPi#25
[2] isarengineering/SecPi#27
[3] https://gist.github.com/amotl/4d8bc928d781a5d0fbc7f404396f8417

Idea: add comment support?

I was wondering if it would be feasible to output comments?

Why? I wrote some code that generates a "reference" config file, with all the keys available to configure an application. I thought that it would be nice to have a comment to each key with some explanation of possible values and what the key does.

Question, is there any plans, interest regarding AoT support?

Hello, thank you very much for the package!

I was wondering if tomli-w has Array of Tables (AoT) support (or at least if you consider this feature something nice to have in the roadmap).
For example, if we take the following conversion:

>>> import tomli_w
>>> example = {'table': {'nested_table': [{'array_options': [1, 2, 3]}, {'another_array': [1, 2]}, {'c': 3}]}}
>>> print(tomli_w.dumps(example))
[table]
nested_table = [
    { array_options = [
    1,
    2,
    3,
] },
    { another_array = [
    1,
    2,
] },
    { c = 3 },
]

The output looks very weird, and a AoT would make it much easier to read... I had to check the standards to believe it is not following a wrong syntax ๐Ÿ˜ (it is explicitly discouraged to have line breaks inside inline tables, though)

In the case AoT is supported, the following would read much nicer:

[[table.nested_table]]
array_options = [
    1,
    2,
    3,
]

[[table.nested_table]]
another_array = [
    1,
    2,
]

[[table.nested_table]]
c = 3

In can see that currently nested tables are automatically handled:

>>> example = {'table': {'nested_table': {'value': 42}}}
>>> print(tomli_w.dumps(example))
[table.nested_table]
value = 42
# instead of "[table]\nnested_table = { value = 42 }"

which conceptually is not very different from AoT, right?

Add `sort_keys` option

As a prettier option and a big improval for tests that compare a toml file, I think a sort_keys like json option is useful.It ensure two toml file with same content will be able to do a text-compare after sorting keys.

Short dict/table values don't get written as inline tables

Problem: Short dict/table values don't get written as inline tables

Version: 1.0.0

code:

import tomli_w
stuff = {'things': {'what':1, "else": 2}}
tomli_w.dumps(stuff)

Current behavior:
output:

[things]
what = 1
else = 2

Expected behavior:
output:

things = { what=1, else=2 }

Extras:
Looking at the code, would we not want to call and check is_suitable_inline_table here? https://github.com/hukkin/tomli-w/blob/master/src/tomli_w/_writer.py#L59-L60

Am I doing something wrong?

`tomli_w.dump` needs output stream to be opened in binary mode

Hi again,

while working on the test case [1] to outline #39, we also found that, when using the access pattern to directly serialize to a file,

with open("testdrive.toml", "wb") as config_file:
    tomli_w.dump(data, config_file)

tomli_w.dump needs the file to be opened in binary mode (wb) and croaks otherwise. Both the other libraries toml and tomlkit do not have that requirement and work well when opening the output stream in text mode (w).

Do you see a chance to adjust tomli-w accordingly?

With kind regards,
Andreas.

[1] https://gist.github.com/amotl/4d8bc928d781a5d0fbc7f404396f8417

Idea: render "simple" lists on one line

Hi! Below, I provide (A) the output of the latest Tomli-W and (B) what I propose for "simple" lists (i.e. those containing only literal values: booleans, numbers, strings, time). The data is a subset of my real TOML file, only keys and strings are replaced with dummy values. In general, I agree with the current "conservative" approach, but it looks like the chance of getting readable output for "simple" lists will be higher with the proposed approach. To avoid too long lines, the length limit similar to this one can be introduced.

# (A)
[a]
b = [
    "k1",
    8,
    512,
]

[c]
d = [
    "k2",
    1,
    8,
    16,
    1024,
]
e = [
    "k3",
    0.0,
    0.0,
    0.5,
]

[f]
g = [
    "k4",
    5e-05,
    0.005,
]
h = [
    "k5",
    1e-06,
    0.001,
]

# (B)
[a]
b = ["k1", 8, 512]

[c]
d = ["k2", 1, 8, 16, 1024]
e = ["k3", 0.0, 0.0, 0.5]

[f]
g = ["k4", 5e-05, 0.005]
h = ["k5", 1e-06, 0.001]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.