flyx / NimYAML

YAML implementation for Nim
https://nimyaml.org
Other
191 stars 36 forks source link

Parent fields cause failure when deserializing child object #131

Closed tanelso2 closed 1 year ago

tanelso2 commented 1 year ago

Hi, NimYAML gives me an error when trying to deserialize a simple object in the code below. It only seems to understand the fields that are directly defined on the type and not any parent types.

Code:

import
    yaml

type
    Parent = object of RootObj
        i*: int
    Child = object of Parent
        s*: string

let sample = """
i: 4
s: hello
"""
var c: Child
load(sample, c)
assert c.i == 4
assert c.s == "hello"

Output:

  nim c -r "/home/thomas/code/yanyl/tests/tnimyaml_inheritance.nim"
Hint: used config file '/home/thomas/.choosenim/toolchains/nim-1.6.10/config/nim.cfg' [Conf]
Hint: used config file '/home/thomas/.choosenim/toolchains/nim-1.6.10/config/config.nims' [Conf]
Hint: used config file '/home/thomas/work/yanyl/tests/nim.cfg' [Conf]
Hint: gc: refc; opt: none (DEBUG BUILD, `-d:release` generates faster code)
9913 lines; 0.011s; 10.699MiB peakmem; proj: /home/thomas/work/yanyl/tests/tnimyaml_inheritance.nim; out: /home/thomas/work/yanyl/tests/tnimyaml_inheritance [SuccessX]
Hint: /home/thomas/work/yanyl/tests/tnimyaml_inheritance  [Exec]
/home/thomas/work/yanyl/tests/tnimyaml_inheritance.nim(15) tnimyaml_inheritance
/home/thomas/.nimble/pkgs/yaml-1.1.0/yaml/serialization.nim(1386) load
/home/thomas/.nimble/pkgs/yaml-1.1.0/yaml/serialization.nim(1362) construct
/home/thomas/.nimble/pkgs/yaml-1.1.0/yaml/serialization.nim(1179) constructChild
/home/thomas/.nimble/pkgs/yaml-1.1.0/yaml/serialization.nim(927) constructObject
/home/thomas/work/yanyl/tests/tnimyaml_inheritance.nim(8) constructObjectDefault
[[reraised from:
/home/thomas/work/yanyl/tests/tnimyaml_inheritance.nim(15) tnimyaml_inheritance
/home/thomas/.nimble/pkgs/yaml-1.1.0/yaml/serialization.nim(1386) load
/home/thomas/.nimble/pkgs/yaml-1.1.0/yaml/serialization.nim(1366) construct
]]
Error: unhandled exception: While constructing Child: Unknown field: "i" [YamlConstructionError]
Error: execution of an external program failed: '/home/thomas/work/yanyl/tests/tnimyaml_inheritance '
flyx commented 1 year ago

It is a known shortcoming that NimYAML doesn't see inherited fields. This was briefly discussed in #130, but a separate issue for it didn't exist yet, so this is the issue for this problem now.

Background: NimYAML currently queries the type definition AST for discovering its fields. This is required for features like properly supporting case in types. However inherited fields are not part of the AST of the target type definition, hence they are currently not processed.

flyx commented 1 year ago

I pushed a commit that handles your test case. I am not quite confident that it works in all scenarios, and dumping is yet to be done, but you can play around with it by installing yaml@#head.

flyx commented 1 year ago

Fixed in NimYAML 2.0.0.