libyaml
libyaml copied to clipboard
Different results for two equivalent representations
Using two different, but theoretically equivalent, representations (quoted string vs literal block)
for the same "object" gives different results when parsed using libyaml
(via pyyaml
) in Python.
This was originally discovered in the context of Ansible and reported here.
Here's a minimal example and the corresponding output:
from yaml import load, CLoader, Loader
def test(string):
print('\x1b[7m# Original input\x1b[27m')
print(string)
print('\x1b[1m# Parsed (libyaml)\x1b[m')
try:
print(load(string, Loader=CLoader))
except Exception as exception:
print('\x1b[1;31m' + str(exception) + '\x1b[m')
data = load(string, Loader=Loader)
print('\x1b[1m# Parsed (pyyaml)\x1b[m')
print(data)
return data
# quoted string == literal block
assert test('key: "\\tvalue\\n"') == test('key: |\n \tvalue\n')
user@host:~/ansible-yaml-loader-issue$ python minimal.py
# Original input
key: "\tvalue\n"
# Parsed (libyaml)
{'key': '\tvalue\n'}
# Parsed (pyyaml)
{'key': '\tvalue\n'}
# Original input
key: |
value
# Parsed (libyaml)
while scanning a block scalar
in "<unicode string>", line 1, column 6
found a tab character where an indentation space is expected
in "<unicode string>", line 2, column 3
# Parsed (pyyaml)
{'key': '\tvalue\n'}
user@host:~/ansible-yaml-loader-issue$
Ansible tries to use the CLoader by default, but if not present it falls back to the Python implementation, so going across platforms that have/lack libyaml users will encounter this issue.
According to "nitzmahone commented on 26 May Closing the Ansible issue, since ultimately this is a packaging issue for pyyaml and Python wheels on some platforms. "So I think this issue can be closed @ingydotnet
@ziyangc97 thanks for looking into it.
Closing for now then...