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

Inherit explicit null as override when decoding json/yaml #1763

Open
steeling opened this issue Nov 23, 2024 · 8 comments
Open

Inherit explicit null as override when decoding json/yaml #1763

steeling opened this issue Nov 23, 2024 · 8 comments
Assignees

Comments

@steeling
Copy link

json.decode doesn't respect nulls properly.

The following example does work as expected:

schema Temp:
    x: int
    y?: int = x

correct: Temp = {x = 1} | {y = None}
incorrect: Temp = {x = 1} | json.decode('{"y": null}')

result:

correct:
  x: 1
  y: null

incorrect:
  x: 1
  y: 1
@Peefy
Copy link
Contributor

Peefy commented Nov 25, 2024

The default attribute operator of the config is : that came from the external config. Thus, 1 | None = 1. If we want to merge like the y = None, we can use the json_merge_patch lib like: https://www.kcl-lang.io/docs/user_docs/support/faq-kcl#use-the-json_merge_patch-module-to-merge-configuration

@steeling
Copy link
Author

We can actually further simplify the request here, which should include this scenario:

m: Temp = json.decode('{"x": 1, "y": null}')

Coming from raw JSON there is no way to explicitly disable optional (but defaulted) values in a schema.

@steeling
Copy link
Author

having some option like json.decode('{}', convert_null_to_none=True) would be nice

@steeling
Copy link
Author

This actually yields some odd behavior:

schema MyObj:
    x: int  
    y?: int = 9

temp: MyObj = json.decode('{"x": 1, "y": null}') 

schema Child:
    parent: MyObj = {y = 2}


output = Child{
    parent: temp
}

The above does not yield the same results as:

schema MyObj:
    x: int  
    y?: int = 9

schema Child:
    parent: MyObj = {y = 2}


output = Child{
    parent:  json.decode('{"x": 1, "y": null}') 
}

@Peefy
Copy link
Contributor

Peefy commented Nov 28, 2024

This is as expected, as for schema, its attribute operator is assumed to be '=' by default. The former is equivalent to merging schema parent and schema temp, while the latter is equivalent to merging schema parent and dict.

@steeling
Copy link
Author

Gotcha that makes sense thanks for the clarification! And as always thanks for the prompt responses :). In regards to this question Is there anyway to cast it to the type I want? Or a way I can do this with a plugin? Or is this something that might be supported in the future?

If willing I’m happy to open a PR related to this if there’s a clear path forward. Maybe passing an optional type to the decode functions?

@Peefy
Copy link
Contributor

Peefy commented Nov 28, 2024

In KCL, they are done automatically and do not require additional type for the decode function.

import json

schema SomeSchema:
    foo: str

    check:
        len(foo) >= 3

# Inst is a schema that satisfies the check condition instead of a dynamic config
inst: SomeSchema = json.decode('{"foo": "bar"}')

@steeling
Copy link
Author

steeling commented Nov 28, 2024

Hmm, so you're saying now that it returns a type, but before you mentioned it returns a dict? In either case there seems to be no current solution to what I'm looking to do?

Specifically I want to consume yaml where a user can set a value to null, even if the value in the schema has a default. I think the below example shows the problem more clearly:

import json

schema SomeSchema:
    foo?: str = "default"


obj1 = json.decode('{"foo": null}')
obj2 = {foo = None}

inst1: SomeSchema = obj1
inst2: SomeSchema = obj2



val = obj1 == obj2

yields:

obj1:
  foo: null
obj2:
  foo: null
inst1:
  foo: default
inst2:
  foo: null
val: true

This shows 2 objects that are equal but have different behavior. This seems like a bug to me, or at the very least a feature deficit. A simple solution could be adding an optional param to decode to enforce explicit nulls.

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

3 participants