概要
勘違いからjson形式の文字列を、yaml.load
で読み込んでしまったのですが、エラーがでず、読み込めてしまったので、不思議に思って調べてみました。
先に結論
YAML1.2からJSONを公式サブセットとする変更が入っているそうです(知らなかった
YAML Ain’t Markup Language (YAML™) Version 1.2
http://yaml.org/spec/1.2/spec.html
This document reflects the third version of YAML data serialization language.
この改訂の主な目的は、YAMLをJSONを公式サブセットとして遵守することです。(Google翻訳)
検証
以下のように、何を思ったのかJSON形式の文字列をYAMLライブラリで読み込んでしまいました。
> pip install pyyaml
import yaml
import pprint
if __name__ == '__main__':
jsonStr = '''
{
"hoge": {
"list": [
{
"name": "hoge",
"value": "foo"
},
{
"name": "huge",
"value": "foo!"
}
]
}
}
'''
pprint.pprint(yaml.load(jsonStr))
> python test.py
{'hoge': {'list': [{'name': 'hoge', 'value': 'foo'},
{'name': 'huge', 'value': 'foo!'}]}}
読み込めてしまったので、あれ?YAMLとJSONって互換性あったっけ?と思い、じゃあjson
ライブラリでYAML形式の文字列読み込めるの?をやってみました。
import json
import pprint
if __name__ == '__main__':
yamlStr = '''
hoge:
list:
- name: hoge
value: foo
- name: huge
value: foo!
'''
pprint.pprint(json.loads(yamlStr))
> python test.py
json.loads(yamlStr)
Traceback (most recent call last):
File "test.py", line 14, in <module>
pprint.pprint(json.loads(yamlStr))
File "/Users/hoge/.anyenv/envs/pyenv/versions/3.6.6/lib/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/Users/hoge/.anyenv/envs/pyenv/versions/3.6.6/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Users/hoge/.anyenv/envs/pyenv/versions/3.6.6/lib/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 2 column 1 (char 1)
だめでした。
PyYAMLが対応しているだけかなと、他のruamel.yamlってライブラリで試してみました。
> pip install ruamel.yaml
from ruamel.yaml import YAML
import pprint
if __name__ == '__main__':
jsonStr = '''
{
"hoge": {
"list": [
{
"name": "hoge",
"value": "foo"
},
{
"name": "huge",
"value": "foo!"
}
]
}
}
'''
yaml=YAML(typ='safe')
pprint.pprint(yaml.load(jsonStr))
> python test.py
{'hoge': {'list': [{'name': 'hoge', 'value': 'foo'},
{'name': 'huge', 'value': 'foo!'}]}}
こちらでも読み込めました。
じゃあ、大抵のYAMLライブラリはJSON形式を読み込める?
と思ってRubyで試してみました。
require 'yaml'
require 'pp'
jsonStr = <<-"EOS"
{
"hoge": {
"list": [
{
"name": "hoge",
"value": "foo"
},
{
"name": "huge",
"value": "foo!"
}
]
}
}
EOS
pp(YAML.load(jsonStr))
> ruby test.rb
{"hoge"=>
{"list"=>
[{"name"=>"hoge", "value"=>"foo"}, {"name"=>"huge", "value"=>"foo!"}]}}
ほう!読み込めるんですね。
YAMLライブラリでJSONは読み込める。
JSONライブラリでYAMLは読み込めない。
なにか見えてきたので、ググってみました。
json --- JSON エンコーダおよびデコーダ
https://docs.python.org/ja/3/library/json.html
注釈 JSON は YAML 1.2 のサブセットです。
YAML Ain’t Markup Language (YAML™) Version 1.2
http://yaml.org/spec/1.2/spec.html
This document reflects the third version of YAML data serialization language.
この改訂の主な目的は、YAMLをJSONを公式サブセットとして遵守することです。
(Google翻訳)
正直、知らなかったです。
ウィキペディアを見てみると英語版の方だと、記載がありました。
making YAML 1.2 a superset of JSON.
日本語版だと類似という記述だけでした。
類似の規格としてJSONがある。
教訓
普段良く使うフォーマットの仕様はしっかり把握しておきましょう。
参考
YAML Ain’t Markup Language (YAML™) Version 1.2
http://yaml.org/spec/1.2/spec.html