使用架构更新文档

当 StrictYAML 使用架构加载文档时,它会检查对该文档的未来更新是否遵循原始架构。

import strictyaml as s
from ensure import Ensure

GitHub #72

doc = s.load('a: 9', s.Map({
  'a': s.Str(),
  s.Optional('b'): s.Int(),
}))
doc['b'] = 9
assert doc['b'] == 9

适用于空映射

doc = s.load('', s.EmptyDict() | s.Map({
  'a': s.Int(),
}))
doc['a'] = 9
assert doc['a'] == 9, doc.as_yaml()

适用于复杂类型

doc = s.load('a: 8', s.Map({'a': s.Int() | s.Float()}))
assert type(doc['a'].data) == int, repr(doc.data)
doc['a'] = '5.'
assert type(doc['a'].data) == float, repr(doc.data)
assert doc['a'] == 5.

不适用于空序列

doc = s.load('', s.EmptyList() | s.Seq(s.Int()))
doc[0] = 9
strictyaml.exceptions.YAMLSerializationError:
cannot extend list via __setitem__.  Instead, replace whole list on parent node.

适用于设置、更新然后设置多个键的映射(回归)

doc = s.load('', s.EmptyDict() | s.MapPattern(
  s.Str(),
  s.EmptyDict() | s.Map({
    s.Optional('b'): s.Seq(s.Int()),
  })
))
doc['a'] = {}
doc['a']['b'] = ['9']
assert doc.data == {'a': {'b': [9]}}, doc.data
assert doc.as_yaml() == 'a:\n  b:\n  - 9\n', doc.as_yaml()
# Second assignment doesn't occur...
doc['a']['b'] = ['9', '10']
assert doc.data == {'a': {'b': [9, 10]}}, doc.data
assert doc.as_yaml() == 'a:\n  b:\n  - 9\n  - 10\n', doc.as_yaml()
# If and only if another node is overwritten.  This was a bug due
# to mismatched _ruamelparsed objects.
doc['b'] = {'b': ['11']}
assert doc['a']['b'].data == [9, 10], doc.data
assert doc['b']['b'].data == [11], doc.data
assert doc.as_yaml() == 'a:\n  b:\n  - 9\n  - 10\nb:\n  b:\n  - 11\n', doc.as_yaml()

对于空序列,必须将整个序列分配为键

doc = s.load('a:', s.Map({'a': s.EmptyList() | s.Seq(s.Int())}))
doc['a'] = [1, 2, 3]
assert doc['a'].data == [1, 2, 3], repr(doc.data)

可以从字符串分配

doc = s.load('a: 9', s.Map({
  'a': s.Str(),
  s.Optional('b'): s.Int(),
}))
doc['b'] = '9'
assert doc['b'] == 9

可执行规范

文档自动从 update-with-schema.story storytests 生成。