(itemiter, dict_cls=dict)
| 179 | |
| 180 | |
| 181 | def decode_flat_data(itemiter, dict_cls=dict): |
| 182 | def _split_key(name): |
| 183 | result = name.split(".") |
| 184 | for idx, part in enumerate(result): |
| 185 | if part.isdigit(): |
| 186 | result[idx] = int(part) |
| 187 | return result |
| 188 | |
| 189 | def _enter_container(container, key): |
| 190 | if key not in container: |
| 191 | return container.setdefault(key, dict_cls()) |
| 192 | return container[key] |
| 193 | |
| 194 | def _convert(container): |
| 195 | if _value_marker in container: |
| 196 | force_list = False |
| 197 | values = container.pop(_value_marker) |
| 198 | if container.pop(_list_marker, False): |
| 199 | force_list = True |
| 200 | values.extend(_convert(x[1]) for x in sorted(container.items())) |
| 201 | if not force_list and len(values) == 1: |
| 202 | values = values[0] |
| 203 | |
| 204 | if not container: |
| 205 | return values |
| 206 | return _convert(container) |
| 207 | if container.pop(_list_marker, False): |
| 208 | return [_convert(x[1]) for x in sorted(container.items())] |
| 209 | return dict_cls((k, _convert(v)) for k, v in container.items()) |
| 210 | |
| 211 | result = dict_cls() |
| 212 | |
| 213 | for key, value in itemiter: |
| 214 | parts = _split_key(key) |
| 215 | if not parts: |
| 216 | continue |
| 217 | container = result |
| 218 | for part in parts: |
| 219 | last_container = container |
| 220 | container = _enter_container(container, part) |
| 221 | last_container[_list_marker] = isinstance(part, int) |
| 222 | container[_value_marker] = [value] |
| 223 | |
| 224 | return _convert(result) |
| 225 | |
| 226 | |
| 227 | def merge(a, b): |
no test coverage detected