libucl
libucl copied to clipboard
Example does not work as described.
So, I was looking at the example in the README.md of the project. I noticed that the first example didn't end up w/ an object named section, despite later in it saying that it should be. I decided to import this into libucl, and export the json, and see how it'd work out, but I got a bigger surprise, the array didn't work like the example implied it should.
This is under python's ucl library, so this COULD be a python library issue. This is using libucl 0.8.1.
$python
Python 3.7.5 (default, Oct 18 2019, 23:59:39)
[Clang 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ucl
>>> examp = '''param = value;
... section {
... param = value;
... param1 = value1;
... flag = true;
... number = 10k;
... time = 0.2s;
... string = "something";
... subsection {
... host = {
... host = "hostname";
... port = 900;
... }
... host = {
... host = "hostname";
... port = 901;
... }
... }
... }'''
>>> u = ucl.load(examp)
>>> print(repr(u))
{'param': 'value', 'section': {'param': 'value', 'param1': 'value1', 'flag': True, 'number': 10000, 'time': '0.2s', 'string': 'something', 'subsection': {'host': {'host': 'hostname', 'port': 900}}}}
>>> import json
>>> print(repr(json.dumps(u)))
'{"param": "value", "section": {"param": "value", "param1": "value1", "flag": true, "number": 10000, "time": "0.2s", "string": "something", "subsection": {"host": {"host": "hostname", "port": 900}}}}'
>>> ^D
$echo '{"param": "value", "section": {"param": "value", "param1": "value1", "flag": true, "number": 10000, "time": "0.2s", "string": "something", "subsection": {"host": {"host": "hostname", "port": 900}}}}' | python -m json.tool
{
"param": "value",
"section": {
"param": "value",
"param1": "value1",
"flag": true,
"number": 10000,
"time": "0.2s",
"string": "something",
"subsection": {
"host": {
"host": "hostname",
"port": 900
}
}
}
}
I expected that the JSON output would match the example in JSON, but there are a number of differences, that being the section is missing in the JSON example, and the list in host in the subsection object, did not get listed as a host.
There is also the fact that number, time and string keys are missing from the section, but that is likely a simple issue w/ the examples not being updated.
if I'm given guidance on what the examples should look like, I'm more than willing to submit an update.
That works fine with Lua.
local u = require "ucl"
local p = u.parser()
p:parse_file('tt.ucl')
print(u.to_json(p:get_object()))
gives:
{
"section": {
"number": 10000,
"subsection": {
"host": [
{
"host": "hostname",
"port": 900
},
{
"host": "hostname",
"port": 901
}
]
},
"flag": true,
"param1": "value1",
"time": 0.200000,
"string": "something",
"param": "value"
},
"param": "value"
}
Unfortunately, I don't know the details about how Python part works as it has been contributed by another person.
I'll take a look at the python. But will you be updating the JSON in the example to match the above? I only even tried this because of the mismatch.
Ok, looks like lua is treating objects as arrays in special, undocumented cases (at least I couldn't find anything about checking obj->next in libucl/doc): https://github.com/vstakhov/libucl/blob/master/lua/lua_ucl.c#L156
Which is why it works, and it doesn't work on the Python code: https://github.com/vstakhov/libucl/blob/master/python/src/uclmodule.c#L46
Yes, multi-value keys were the biggest design mistake in UCL, I agree :(
why not simply change libucl to return the object as an array when that happens? at least it'd give expected results in that consumers should be treating them as arrays instead of objects.
It'd also catch cases where consumers weren't expecting an object become array, and also handle the POLA case where the consumer wasn't handling it (e.g. this python library), and the other objects just disappear, or ignored causing the end user no idea WHY their configuration isn't working the way they expected it to.
why not simply change libucl to return the object as an array when that happens?
libucl has a parser flag to do that: UCL_PARSER_NO_IMPLICIT_ARRAYS
Ok, adding the flag fixes UCL_PARSER_NO_IMPLICIT_ARRAYS the python test case. I'll submit a PR for Python module including a test for this case.