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

Custom tags are evaluated after solving the union operators. But they must be calculated before them. #814

Open
sergey-gru opened this issue Jul 6, 2024 · 0 comments

Comments

@sergey-gru
Copy link

I'm trying to implement a file include operation using tag syntax. I am convinced that I wrote the classes correctly:

import yaml

class YamlLoaderInclude(yaml.SafeLoader):
    def __init__(self, stream):
        super().__init__(stream)


class YamlInclude(yaml.YAMLObject):
    yaml_tag = '!include'
    yaml_loader = YamlLoaderInclude

    @classmethod
    def from_yaml(cls, loader: YamlLoaderInclude, node) -> dict:
        arg = loader.construct_scalar(node)
        p = arg.strip().strip('"').strip("'")
        # data = include_yaml(p)
        data = { a: 1, b: 2 }

        return data

Here is the file to include.

#include.yaml

a: &a !include inc.yaml # Ok
<<: !include inc.yaml   # error
<<: *a  # it's literally the same as <<: !include inc.yaml

This is the output after running my autotests with this file. line and column in the logs point to the beginning of the tag !include

Traceback (most recent call last):
  File "D:\Projects\project\py_test\test_environ.py", line 90, in test_1_load_include
    data = loader.data
           ^^^^^^^^^^^
  File "D:\Projects\project\py\environ.py", line 126, in data
    self._data = self._yaml_parse()
                 ^^^^^^^^^^^^^^^^^^
  File "D:\Projects\project\py\environ.py", line 112, in _yaml_parse
    return loader.get_data()
           ^^^^^^^^^^^^^^^^^
  File "D:\Projects\project\.venv\Lib\site-packages\yaml\constructor.py", line 45, in get_data
    return self.construct_document(self.get_node())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Projects\project\.venv\Lib\site-packages\yaml\constructor.py", line 60, in construct_document
    for dummy in generator:
  File "D:\Projects\project\.venv\Lib\site-packages\yaml\constructor.py", line 414, in construct_yaml_map
    value = self.construct_mapping(node)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Projects\project\.venv\Lib\site-packages\yaml\constructor.py", line 217, in construct_mapping
    self.flatten_mapping(node)
  File "D:\Projects\project\.venv\Lib\site-packages\yaml\constructor.py", line 204, in flatten_mapping
    raise ConstructorError("while constructing a mapping", node.start_mark,
yaml.constructor.ConstructorError: while constructing a mapping
  in "D:\Projects\project\py_test\environ\include.yaml", line 2, column 1
expected a mapping or list of mappings for merging, but found scalar
  in "D:\Projects\project\py_test\environ\include.yaml", line 11, column 4

After reading the code, it turned out that this is due to the fact that the library does not calculate tags before merging. On the contrary, it calculates them after the merger.

Regarding anchors, the library simply copies their contents, and the custom tags are expected to be evaluated before

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

1 participant