You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/changelog.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,9 @@
1
1
# Changelog
2
2
3
+
### 1.1.0 - Now load objects from sequences and scalars too
4
+
5
+
- Objects (subclasses of `YamlAble` or `YamlObject2`) can now be loaded from both mappings, sequences and scalars. Codecs (subclasses of `YamlCodec`) can also support this feature. Fixes [#12](https://github.com/smarie/python-yamlable/issues/12)
6
+
3
7
### 1.0.4 - better type hinting (mypy)
4
8
5
9
- Most type hints have been fixed, in particular for `@yaml_info`. Fixes [#11](https://github.com/smarie/python-yamlable/issues/11).
Copy file name to clipboardExpand all lines: docs/index.md
+45-2Lines changed: 45 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,6 +26,10 @@ In addition `yamlable` provides a way to create Yaml codecs for several object t
26
26
27
27
## Usage
28
28
29
+
### 1. The (recommended) `YamlAble` way
30
+
31
+
#### a. Creating the class
32
+
29
33
Let's make a class yaml-able: we have to
30
34
31
35
- inherit from `YamlAble`
@@ -38,7 +42,7 @@ from yamlable import yaml_info, YamlAble
38
42
@yaml_info(yaml_tag_ns='com.yamlable.example')
39
43
classFoo(YamlAble):
40
44
41
-
def__init__(self, a, b):
45
+
def__init__(self, a, b="hey"):
42
46
""" Constructor """
43
47
self.a = a
44
48
self.b = b
@@ -67,6 +71,8 @@ That's it! Let's check that our class is correct and allows us to create instanc
67
71
Foo - {'a': 1, 'b': 'hello'}
68
72
```
69
73
74
+
#### b. Dumping and loading to/from YAML
75
+
70
76
Now let's dump and load it using `pyyaml`:
71
77
72
78
```python
@@ -105,7 +111,44 @@ a: 1
105
111
b: hello
106
112
```
107
113
108
-
See [Usage](./usage) for other possibilities of `yamlable`.
114
+
#### c. Support for sequences and scalars
115
+
116
+
Objects can also be loaded from YAML sequences:
117
+
118
+
```python
119
+
>>>print(yaml.safe_load("""
120
+
!yamlable/com.yamlable.example.Foo
121
+
- 0
122
+
- hey
123
+
"""))
124
+
125
+
Foo - {'a': 0, 'b': 'hey'}
126
+
```
127
+
128
+
The default implementation of `__from_yaml_sequence__` (that you may wish to override in your subclass), is to call
129
+
the constructor with the sequence contents as positional arguments.
130
+
131
+
The same also works for scalars:
132
+
133
+
```python
134
+
>>>print(yaml.safe_load("""
135
+
!yamlable/com.yamlable.example.Foo 0
136
+
"""))
137
+
138
+
Foo - {'a': "0", 'b': 'hey'}
139
+
```
140
+
141
+
The default implementation of `__from_yaml_scalar__` (that you may wish to override in your subclass), is to call
142
+
the constructor with the scalar as first positional argument.
143
+
144
+
!!! warning "Scalars are not resolved"
145
+
As can be seen in the above example, scalars are not auto-resolved when constructing an object from a scalar. So an
146
+
integer `0` is actually received as a string `"0"` by `from_yaml_scalar`.
147
+
148
+
149
+
#### d. What if you can not modify the class ?
150
+
151
+
See [Usage](./usage#yamlcodec) for another possibility offered by `yamlable`: creating a codec to handle YAML for several classes at once, typically classes that you cannot modify.
Copy file name to clipboardExpand all lines: docs/usage.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,8 @@ You have seen in the [main page](./index) a small example to understand the conc
4
4
5
5
## `YamlCodec`
6
6
7
+
### 1. Writing a codec class
8
+
7
9
Sometimes you do not have the possibility to change the classes of the objects that you wish to encode/decode. In this case the solution is to write an independent codec, inheriting from `YamlCodec`. Once again this feature leverages the `multi_constructor` and `multi_representer` concepts available in the `PyYaml` internals, but with `YamlCodec` it becomes a bit easier to do.
8
10
9
11
Let's assume that the following two classes are given and can not be modified:
@@ -84,13 +86,17 @@ class MyCodec(YamlCodec):
84
86
return types_to_yaml_tags[type(obj)], vars(obj)
85
87
```
86
88
89
+
### 2. Registering a codec
90
+
87
91
When you codec has been defined, it needs to be registerd before being usable. You can specify with which `PyYaml` Loaders/Dumpers it should be registered, or use the default (all):
88
92
89
93
```python
90
94
# register the codec
91
95
MyCodec.register_with_pyyaml()
92
96
```
93
97
98
+
### 3. Using a codec
99
+
94
100
Finally let's test that the codec works:
95
101
96
102
```python
@@ -111,3 +117,10 @@ assert dump(b) == by
111
117
assert f == load(fy)
112
118
assert b == load(by)
113
119
```
120
+
121
+
### 4. Sequences and scalars
122
+
123
+
Objects can be loaded from sequences and scalars, in addition to dictionaries. To support this possibility, you simply need to fill the class methods:
0 commit comments