70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from __future__ import absolute_import
|
|
|
|
from benedict.serializers.abstract import AbstractSerializer
|
|
from benedict.utils import type_util
|
|
|
|
try:
|
|
from configparser import ConfigParser
|
|
from configparser import DEFAULTSECT as default_section
|
|
except ImportError:
|
|
from ConfigParser import ConfigParser
|
|
default_section = 'DEFAULT'
|
|
|
|
from six import PY2, StringIO
|
|
|
|
|
|
class INISerializer(AbstractSerializer):
|
|
|
|
def __init__(self):
|
|
super(INISerializer, self).__init__()
|
|
|
|
@staticmethod
|
|
def _get_section_option_value(parser, section, option):
|
|
value = None
|
|
funcs = [
|
|
parser.getint,
|
|
parser.getfloat,
|
|
parser.getboolean,
|
|
parser.get,
|
|
]
|
|
for func in funcs:
|
|
try:
|
|
value = func(section, option)
|
|
break
|
|
except ValueError:
|
|
continue
|
|
return value
|
|
|
|
def decode(self, s, **kwargs):
|
|
parser = ConfigParser(**kwargs)
|
|
if PY2:
|
|
parser.readfp(StringIO(s))
|
|
else:
|
|
parser.read_string(s)
|
|
data = {}
|
|
for option, _ in parser.defaults().items():
|
|
data[option] = self._get_section_option_value(
|
|
parser, default_section, option)
|
|
for section in parser.sections():
|
|
data[section] = {}
|
|
for option, _ in parser.items(section):
|
|
data[section][option] = self._get_section_option_value(
|
|
parser, section, option)
|
|
return data
|
|
|
|
def encode(self, d, **kwargs):
|
|
parser = ConfigParser(**kwargs)
|
|
for key, value in d.items():
|
|
if not type_util.is_dict(value):
|
|
parser.set(default_section, key, '{}'.format(value))
|
|
continue
|
|
section = key
|
|
parser.add_section(section)
|
|
for option_key, option_value in value.items():
|
|
parser.set(section, option_key, '{}'.format(option_value))
|
|
str_data = StringIO()
|
|
parser.write(str_data)
|
|
return str_data.getvalue()
|