Passed
Pull Request — master (#40)
by
unknown
55s
created

benedict.serializers.ini   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 16
eloc 53
dl 0
loc 71
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A INISerializer.encode() 0 8 2
A INISerializer._try_parse() 0 12 4
A INISerializer.decode() 0 11 3
B INISerializer._preprocessed_dict() 0 20 6
A INISerializer.__init__() 0 2 1
1
# -*- coding: utf-8 -*-
2
3
from __future__ import absolute_import
4
5
import io
6
import configparser
7
8
from benedict.core import clone
9
from benedict.serializers.abstract import AbstractSerializer
10
11
12
class INISerializer(AbstractSerializer):
13
14
    def __init__(self):
15
        super(INISerializer, self).__init__()
16
17
    @staticmethod
18
    def _try_parse(parser: configparser.ConfigParser, section, key):
19
        try:
20
            return parser.getint(section, key)
21
        except ValueError:
22
            try:
23
                return parser.getfloat(section, key)
24
            except ValueError:
25
                try:
26
                    return parser.getboolean(section, key)
27
                except ValueError:
28
                    return parser.get(section, key)
29
30
    def decode(self, s, **kwargs):
31
        parser = configparser.ConfigParser()
32
        kwargs.setdefault("source", "<string>")
33
        parser.read_string(s, **kwargs)
34
        data = {}
35
        for s in parser.sections():
36
            data[s] = {}
37
            for key, _ in parser.items(s):
38
                data[s][key] = INISerializer._try_parse(parser, s, key)
39
40
        return data
41
42
    def encode(self, d, **kwargs):
43
        parser = configparser.ConfigParser()
44
        processed_dict = self._preprocessed_dict(d, **kwargs)
45
        parser.read_dict(processed_dict)
46
        with io.StringIO() as data:
47
            parser.write(data, **kwargs)
48
            data.seek(0)
49
            return data.getvalue()
50
51
    def _preprocessed_dict(self, d, default_namespace="default"):
52
        sections = {
53
            default_namespace: {}
54
        }
55
        for key, value in d.items():
56
            if isinstance(value, dict):
57
                sections[key] = clone(value)
58
            else:
59
                sections[default_namespace][key] = value
60
61
        # Stringify all the value
62
        for section in sections.values():
63
            for key, val in section.items():
64
                section[key] = str(val)
65
66
        # if the default section is empty, delete it
67
        if len(sections[default_namespace]) == 0:
68
            del sections[default_namespace]
69
70
        return sections
71