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

Example does not work as described. #233

Open
jmgurney opened this issue Sep 10, 2020 · 8 comments
Open

Example does not work as described. #233

jmgurney opened this issue Sep 10, 2020 · 8 comments

Comments

@jmgurney
Copy link
Contributor

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.

@jmgurney
Copy link
Contributor Author

if I'm given guidance on what the examples should look like, I'm more than willing to submit an update.

@vstakhov
Copy link
Owner

vstakhov commented Sep 14, 2020

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.

@jmgurney
Copy link
Contributor Author

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.

@jmgurney
Copy link
Contributor Author

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

@vstakhov
Copy link
Owner

Yes, multi-value keys were the biggest design mistake in UCL, I agree :(

@jmgurney
Copy link
Contributor Author

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.

@vstakhov
Copy link
Owner

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

@jmgurney
Copy link
Contributor Author

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.

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