Re: [netmod] json empty leaf encoding strangeness [Re: WG Last Call for draft-ietf-netmod-yang-json-04 (until 2015-06-29)]

Eliot Lear <lear@lear.ch> Sat, 18 December 2021 08:54 UTC

Return-Path: <lear@lear.ch>
X-Original-To: netmod@ietfa.amsl.com
Delivered-To: netmod@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id AF1453A08C5 for <netmod@ietfa.amsl.com>; Sat, 18 Dec 2021 00:54:24 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -3.941
X-Spam-Level:
X-Spam-Status: No, score=-3.941 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, NICE_REPLY_A=-1.852, SPF_PASS=-0.001, T_SPF_HELO_PERMERROR=0.01, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=lear.ch
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yXvSp7Iw9o12 for <netmod@ietfa.amsl.com>; Sat, 18 Dec 2021 00:54:19 -0800 (PST)
Received: from upstairs.ofcourseimright.com (upstairs.ofcourseimright.com [185.32.222.29]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id C12DE3A08C4 for <netmod@ietf.org>; Sat, 18 Dec 2021 00:54:18 -0800 (PST)
Received: from [192.168.0.227] (77-58-147-26.dclient.hispeed.ch [77.58.147.26]) (authenticated bits=0) by upstairs.ofcourseimright.com (8.15.2/8.15.2/Debian-18) with ESMTPSA id 1BI8sDHU1214630 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NO); Sat, 18 Dec 2021 09:54:14 +0100
Authentication-Results: upstairs.ofcourseimright.com; dmarc=none (p=none dis=none) header.from=lear.ch
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=lear.ch; s=upstairs; t=1639817654; bh=LK7pMny2GWktNextU7mP6aqbgneYHLOXqvJqp2AAH8k=; h=Date:Subject:From:To:Cc:References:In-Reply-To:From; b=MhthYR916RabG2V2otzCrUuscxtnERd5Qx8ZUefPZhENH2zVNkvMku4ngugc9oKdg DYV7VrFZj0UezWMgCI8Jkk8XTiVUmZkaxzLejkQzodq+JiyGiGBR31MJK4e3q06FyP SyhBCKK3DdZAEwkMmZ0N4sO8a4EdDGP9JpeWoXLc=
Message-ID: <39dd4f17-a537-d20b-ba83-5252686f7b5e@lear.ch>
Date: Sat, 18 Dec 2021 09:54:11 +0100
MIME-Version: 1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Thunderbird/91.4.0
Content-Language: en-US
From: Eliot Lear <lear@lear.ch>
To: Christian Hopps <chopps@chopps.org>, "netmod@ietf.org" <netmod@ietf.org>
Cc: Ladislav Lhotka <lhotka@nic.cz>
References: <D1A4CEB7.B22F7%kwatsen@juniper.net> <20150624145325.GB38016@elstar.local> <m2lhf27sko.fsf@birdie.labs.nic.cz> <1640D503-A676-4BC5-82E6-E08ED04F7106@chopps.org> <4d8189be-aeea-9ed9-b43f-80580acd2b9a@lear.ch>
In-Reply-To: <4d8189be-aeea-9ed9-b43f-80580acd2b9a@lear.ch>
Content-Type: multipart/signed; micalg="pgp-sha256"; protocol="application/pgp-signature"; boundary="------------djoaD8y7iylXLozqroz2xkJy"
Archived-At: <https://mailarchive.ietf.org/arch/msg/netmod/Toe19WJW3yOVMgTz0Ee3sEf6nRc>
Subject: Re: [netmod] json empty leaf encoding strangeness [Re: WG Last Call for draft-ietf-netmod-yang-json-04 (until 2015-06-29)]
X-BeenThere: netmod@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: NETMOD WG list <netmod.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/netmod>, <mailto:netmod-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/netmod/>
List-Post: <mailto:netmod@ietf.org>
List-Help: <mailto:netmod-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/netmod>, <mailto:netmod-request@ietf.org?subject=subscribe>
X-List-Received-Date: Sat, 18 Dec 2021 08:54:25 -0000

Just following this up, I see in my own work it occurs a little bit, so 
it is out there.  It doesn't create ambiguities, tho, because it is used 
in null-valued leafs.  It just creates syntax breakage.  Some parsers 
will have a problem with recognizing a naked null as valid.  On the 
other hand, in the case of MUD, we separately added versioning into the 
model, so we could bump this if the serialization updates.

On 18.12.21 09:20, Eliot Lear wrote:
>
> Possibly.  The issue with fixing it is that it would create an 
> ambiguity between null and [  null ].  I am not sure how often [ null 
> ] would not have that semantic equivalence in earlier work.  This is 
> further complicated by a lack of self-descriptive versioning in YANG 
> serializations.
>
> Still it seems like the right thing to do, in order to fall into line 
> with the target language spec.
>
> Eliot
>
> On 18.12.21 07:47, Christian Hopps wrote:
>> Hi,
>>
>> I was just going over json encoding of YANG, and got to the empty 
>> leaf encoding and it's odd use of "[null]" rather than just "null". I 
>> read the explanation, but had a hard time believing what it said. So, 
>> running code time. The first thing I tried was Python to see if 
>> something weird happened:
>>
>>     In [1]: import json
>>     In [2]: json.loads('{"foo": null}')
>>     Out[2]: {'foo': None}
>>
>> Nope, seems fine. Then checked the "definitive source" for json, 
>> javascript:
>>
>>     js> JSON.parse("{\"foo\": 1, \"bar\": null}")
>>     ({foo:1, bar:null})
>>
>>
>> Seems fine here too..
>>
>> So I went searching the mailing list and found this:
>>
>>>     On Jun 29, 2015, at 5:49 AM, Ladislav Lhotka <lhotka@nic.cz> wrote:
>>>     Juergen Schoenwaelder <j.schoenwaelder@jacobs-university.de> writes:
>>     ...
>>>>     - I am not sure I understand the argument why [null] is better than
>>>>      null for the empty type. Perhaps it is but the text does not
>>>>     really
>>>>      tell me.
>>>
>>>     "foo": null
>>>
>>>     may sometimes appear as if the "foo" instance is not present at
>>>     all - in
>>>     some languages this is probably more serious than in others.
>>>     This is how
>>>     it works in Python:
>>>
>>>>>>     import json
>>>>>>     obj = json.loads('{"foo": null, "bar": [null]}')
>>>>>>     "YES" if obj["foo"] else "NO"
>>>     'NO'
>>>>>>     "YES" if obj["bar"] else "NO"
>>>     'YES'
>>>
>>>     So the special value "[null]" seems safer and it cannot appear
>>>     in any
>>>     other context.
>>
>> The justifying example here is, unfortunately, wrong. One does not 
>> (normally) check for the presence of a dictionary item in python by 
>> trying to access the value of that item (which is what the code above 
>> is doing). The standard python code to check for the presence of an 
>> item is as follows, and it works fine with a "null" json value:
>>
>>     In [1]: import json
>>     In [2]: o = json.loads('{"foo": null}')
>>     In [3]: o
>>     Out[3]: {'foo': None}
>>     In [4]: "YES" if "foo" in o else "NO"
>>     Out[4]: 'YES'
>>
>> Indeed in python if you try and check for a missing item the way the 
>> email above describes, and the item is missing, an exception is raised:
>>
>>     In [5]: o["bar"]
>>     ---------------------------------------------------------------------------
>>     KeyError                                Traceback (most recent
>>     call last)
>>
>>
>> One *could* catch the "KeyError" to check for missing items which 
>> will also work using "null" son values for empty leafs, but the more 
>> common form is "if key in dict" in my experience.
>>
>> Furthermore, using "access the value" for presence check will also 
>> "fail" for zero values and for empty strings, but we don't have odd 
>> encodings for integers or strings...
>>
>>     In [1]: import json
>>     In [2]: o = json.loads('{"foo": 0, "bar": ""}')
>>     In [3]: o
>>     Out[3]: {'foo': 0, 'bar': ''}
>>     In [4]: "YES" if o["foo"] else "NO"
>>     Out[4]: 'NO'
>>     In [5]: "YES" if o["bar"] else "NO"
>>     Out[5]: 'NO'
>>
>>
>> Point being, evaluating an items value is not the right way to check 
>> for "presence", it's the way to check the "value" of the item. An 
>> empty leaf has no value so it's basically never correct to try to 
>> access that value in code.
>>
>> Javascript is basically the same as python here:
>>
>>     js> o = JSON.parse('{"foo": null}')
>>     ({foo:null})
>>     js> if ("foo" in o) { "YES" } else { "NO" }
>>     "YES"
>>
>>
>> So, do we think it would it ever be possible to change (fix) this 
>> encoding oddity?
>>
>> Thanks,
>> Chris.
>>
>>
>> _______________________________________________
>> netmod mailing list
>> netmod@ietf.org
>> https://www.ietf.org/mailman/listinfo/netmod
>
> _______________________________________________
> netmod mailing list
> netmod@ietf.org
> https://www.ietf.org/mailman/listinfo/netmod