1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
---
title: Updating document with a schema
---
When StrictYAML loads a document with a schema, it checks that future
updates to that document follow the original schema.
```python
import strictyaml as s
from ensure import Ensure
```
GitHub \#72:
```python
doc = s.load('a: 9', s.Map({
'a': s.Str(),
s.Optional('b'): s.Int(),
}))
doc['b'] = 9
assert doc['b'] == 9
```
Works on empty mapping:
```python
doc = s.load('', s.EmptyDict() | s.Map({
'a': s.Int(),
}))
doc['a'] = 9
assert doc['a'] == 9, doc.as_yaml()
```
Works on complex types:
```python
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.
```
Will not work on empty sequence:
```python
doc = s.load('', s.EmptyList() | s.Seq(s.Int()))
doc[0] = 9
```
```python
strictyaml.exceptions.YAMLSerializationError:
cannot extend list via __setitem__. Instead, replace whole list on parent node.
```
Works on map with setting, updating, and then setting multiple keys (regression):
```python
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()
```
For empty sequence, must instead assign whole sequence as key:
```python
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)
```
Can assign from string:
```python
doc = s.load('a: 9', s.Map({
'a': s.Str(),
s.Optional('b'): s.Int(),
}))
doc['b'] = '9'
assert doc['b'] == 9
```
!!! note "Executable specification"
Documentation automatically generated from
<a href="https://github.com/crdoconnor/strictyaml/blob/master/hitch/story/update-with-schema.story">update-with-schema.story
storytests.
|