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

Consider Sequence Support? #12

Closed
rainydew opened this issue Jan 17, 2022 · 7 comments · Fixed by #13
Closed

Consider Sequence Support? #12

rainydew opened this issue Jan 17, 2022 · 7 comments · Fixed by #13

Comments

@rainydew
Copy link

# coding: utf-8
from yamlable import YamlObject2
import yaml

class Base:
    def __init__(self, *args, **kwargs):
        print("here", args, kwargs)
        self.args = args
        self.kwargs = kwargs

    def __repr__(self):
        return f"{self.__dict__}"


class Ice(YamlObject2, Base):
    yaml_tag = "![*ice]"


class Fire(YamlObject2, Base):
    yaml_tag = "![*fire]"


file = """
dict:
  - &ice ~
  - &fire ~
data:
  - ![*ice] {k: 1, v: 2}
  - ![*fire] [1, 2]
"""

data = yaml.safe_load(file)

print(data)

When parsing Ice (mapping, to dict), everything works well. However YamlAble doesn't have a handler to handle sequence yet, it will cause
`
E:\Python36\python.exe C:/Users/Administrator/AppData/Roaming/JetBrains/PyCharm2020.1/scratches/test_scratch.py
here () {'k': 1, 'v': 2}

Traceback (most recent call last):
File "C:/Users/Administrator/AppData/Roaming/JetBrains/PyCharm2020.1/scratches/test_scratch.py", line 31, in
data = yaml.safe_load(file)
File "E:\Python36\lib\site-packages\yaml_init_.py", line 162, in safe_load
return load(stream, SafeLoader)
File "E:\Python36\lib\site-packages\yaml_init_.py", line 114, in load
return loader.get_single_data()
File "E:\Python36\lib\site-packages\yaml\constructor.py", line 51, in get_single_data
return self.construct_document(node)
File "E:\Python36\lib\site-packages\yaml\constructor.py", line 60, in construct_document
for dummy in generator:
File "E:\Python36\lib\site-packages\yaml\constructor.py", line 408, in construct_yaml_seq
data.extend(self.construct_sequence(node))
File "E:\Python36\lib\site-packages\yaml\constructor.py", line 130, in construct_sequence
for child in node.value]
File "E:\Python36\lib\site-packages\yaml\constructor.py", line 130, in
for child in node.value]
File "E:\Python36\lib\site-packages\yaml\constructor.py", line 100, in construct_object
data = constructor(self, node)
File "E:\Python36\lib\site-packages\yamlable\yaml_objects.py", line 115, in from_yaml
constructor_args = read_yaml_node_as_dict(loader, node)
File "E:\Python36\lib\site-packages\yamlable\base.py", line 210, in read_yaml_node_as_dict
loader.flatten_mapping(node)
File "E:\Python36\lib\site-packages\yaml\constructor.py", line 184, in flatten_mapping
key_node, value_node = node.value[index]
TypeError: 'ScalarNode' object is not iterable
`

Maybe a type router to call constructor in different ways is better?

@smarie
Copy link
Owner

smarie commented Jan 21, 2022

Thanks @rainydew ! Indeed YAMLObject2 considers that your object is represented as a yaml dict for now.

Before going further on how to improve yamlable, would you know if/how pyyaml.YAMLObject handles this ? If reading objects from sequences is confirmed to be a valid scenario, we can definitely improve the lib (I would be happy to review a PR if you wish to give a try).

@smarie
Copy link
Owner

smarie commented Jan 21, 2022

I just had a look, pyyaml does not support it:

import yaml

class Hero:
    def __init__(self, name, hp, sp):
        self.name = name
        self.hp = hp
        self.sp = sp

    def __repr__(self):
        return "%s(name=%r, hp=%r, sp=%r)" % (self.__class__.__name__, self.name, self.hp, self.sp)

yaml.load("""
!!python/object:__main__.Hero
- Welthyr Syxgon
- 1200
- 0
""")

fails with

yaml.constructor.ConstructorError: expected a mapping node, but found sequence
  in "<unicode string>", line 2, column 1:
    !!python/object:__main__.Hero

@smarie
Copy link
Owner

smarie commented Jan 21, 2022

Same with scalar:

yaml.load("""
!!python/object:__main__.Hero
Welthyr Syxgon
""")

raises

yaml.constructor.ConstructorError: expected a mapping node, but found scalar
  in "<unicode string>", line 2, column 1:
    !!python/object:__main__.Hero

@smarie
Copy link
Owner

smarie commented Feb 7, 2022

Hi @rainydew , the feature should now be available in yamlable version 1.1.0
I took this opportunity also to improve the examples using mkdocs-gallery. Let me know what you think ! ;)

@rainydew
Copy link
Author

rainydew commented Feb 8, 2022

hi @smarie sorry quite busy recently, thanks a lot for improving and i will try soon~

@rainydew
Copy link
Author

rainydew commented Mar 1, 2022

hi @smarie thanks it works wonderful and can do lots of work with python IDE like pycharm... (for tag hint and auto complete it can make lots of function and be very flexible, can use as DSL)

@smarie
Copy link
Owner

smarie commented Mar 2, 2022

Super cool ! Thanks @rainydew for the feedback

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

Successfully merging a pull request may close this issue.

2 participants