KenKundert / nestedtext

Human readable and writable data interchange format
https://nestedtext.org
MIT License
362 stars 13 forks source link

Empty collections cannot be round-tripped #8

Closed dbowring closed 3 years ago

dbowring commented 3 years ago
>>> import json
>>> import nestedtext as nt
>>> import yaml

>>> empty_dict = {}
>>> json.loads(json.dumps(empty_dict)) == empty_dict
True
>>> yaml.load(yaml.dump(empty_dict)) == empty_dict
True
>>> nt.loads(nt.dumps(empty_dict)) == empty_dict
False

>>> empty_list = []
>>> json.loads(json.dumps(empty_list)) == empty_list
True
>>> yaml.load(yaml.dump(empty_list)) == empty_list
True
>>> nt.loads(nt.dumps(empty_list)) == empty_list
False

>>> sample_data = {"links": {}, "tags": []}
>>> nt.dumps(sample_data)
'links:\n\ntags:\n'
>>> nt.loads(_)
{'links': '', 'tags': ''}

Very interested in this as a yaml alternative, but this would be a blocker for me.

yunruse commented 3 years ago

In other words, what would return falsy dicts and lists instead returns None.

This has... some legitimacy: all of [], {}, None are falsy, so namedtext.load(...) or default should be fine. However dict.update and other methods would be a little bit of a headache here.

I would therefore recommend the data type be as given, with None only for falsy input eg nestedtext.loads('').

KenKundert commented 3 years ago

This looks like a bug in dump. Give me some time to look into it.

KenKundert commented 3 years ago

Upon further review, this is not a bug at all. Rather it is a rather unexpected consequence of the design decision that all leaf values must be strings. At the moment I don't see that changing.

The current behavior of NestedText is consisted with the idea that you use NestedText files to hold the values without any information about the type of those values. Instead it is up to the end application to know what type to expect for a particular value and do the conversion itself. Fortunately, one can use voluptuous to do easily do the conversion.

It turns out that this report did uncover a bug. dump() should not allow empty dictionaries and lists when default='strict' is specified. That will be corrected.