概要
勘違いから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
test.py
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形式の文字列読み込めるの?をやってみました。
test.py
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
test.py
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で試してみました。
test.rb
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翻訳)
正直、知らなかったです。
ウィキペディアを見てみると英語版の方だと、記載がありました。
https://en.wikipedia.org/wiki/YAML
making YAML 1.2 a superset of JSON.
日本語版だと類似という記述だけでした。
https://ja.wikipedia.org/wiki/YAML
類似の規格としてJSONがある。
教訓
普段良く使うフォーマットの仕様はしっかり把握しておきましょう。
参考
YAML Ain’t Markup Language (YAML™) Version 1.2
http://yaml.org/spec/1.2/spec.html
YAML
https://en.wikipedia.org/wiki/YAML