File: yaml.py

package info (click to toggle)
ansible-core 2.19.0~beta6-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 32,628 kB
  • sloc: python: 180,313; cs: 4,929; sh: 4,601; xml: 34; makefile: 21
file content (53 lines) | stat: -rw-r--r-- 2,325 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
# Copyright: (c) 2017, Ansible Project
# Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import annotations

import json
import typing as t

import yaml

from ansible.errors import AnsibleJSONParserError
from ansible._internal._errors import _error_utils
from ansible.parsing.vault import VaultSecret
from ansible.parsing.yaml.loader import AnsibleLoader
from ansible._internal._yaml._errors import AnsibleYAMLParserError
from ansible._internal._datatag._tags import Origin
from ansible._internal._json._profiles import _legacy


def from_yaml(
    data: str,
    file_name: str | None = None,
    show_content: bool = True,
    vault_secrets: list[tuple[str, VaultSecret]] | None = None,  # deprecated: description='Deprecate vault_secrets, it has no effect.' core_version='2.23'
    json_only: bool = False,
) -> t.Any:
    """Creates a Python data structure from the given data, which can be either a JSON or YAML string."""
    # FUTURE: provide Ansible-specific top-level APIs to expose JSON and YAML serialization/deserialization to hide the error handling logic
    #         once those are in place, defer deprecate this entire function

    origin = Origin.get_or_create_tag(data, file_name)

    data = origin.tag(data)

    with _error_utils.RedactAnnotatedSourceContext.when(not show_content):
        try:
            # we first try to load this data as JSON.
            # Fixes issues with extra vars json strings not being parsed correctly by the yaml parser
            return json.loads(data, cls=_legacy.Decoder)
        except Exception as ex:
            json_ex = ex

        if json_only:
            AnsibleJSONParserError.handle_exception(json_ex, origin=origin)

        try:
            return yaml.load(data, Loader=AnsibleLoader)  # type: ignore[arg-type]
        except Exception as yaml_ex:
            # DTFIX-FUTURE: how can we indicate in Origin that the data is in-memory only, to support context information -- is that useful?
            #        we'd need to pass data to handle_exception so it could be used as the content instead of reading from disk
            AnsibleYAMLParserError.handle_exception(yaml_ex, origin=origin)