次のコードは、無限にネストされた Python リストを生成します。
import yaml
i_list = yaml.load('&id1 [3, *id1]')
print i_list
# [3, [...]]
print i_list[1] is i_list
# True
list
Python の種類について明示的に言及することもできます。
i_list = yaml.load('&id1 !!python/list [3, *id1]')
また、次のように、yaml を解析せずにその構造を手動で作成することもできます。
i_list = [3]
i_list.append(i_list)
ただし、最後のトリックは、タプルやその他の不変オブジェクトには機能しません。無限にネストされたタプルを作成するには、CPython の API を使用する必要があります。
from ctypes import pythonapi
from _ctypes import PyObj_FromPtr
t = pythonapi.PyTuple_New(1)
pythonapi.PyTuple_SetItem(t, 0, t)
i_tup = PyObj_FromPtr(t)
print repr(i_tup)
# ((...),)
このようなタプルに期待される yaml コードは次のようになります。
&id001 !!python/tuple
- *id001
実際、これは の出力ですyaml.dump(i_tup)
。ただし、python の yaml はまったく同じコードをロードできません。
yaml.load(yaml.dump(i_tup))
ConstructorError: found unconstructable recursive node
in "<string>", line 1, column 1:
&id001 !!python/tuple
^
それがそうである正当な理由はありますか?あなたが提案できる回避策はありますか?