Skip to content

Commit

Permalink
Allow ini format to support nested structures. (fabiocaccamo#289)
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiocaccamo authored May 16, 2023
1 parent 9e07e48 commit 84fa1c8
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 4 deletions.
19 changes: 15 additions & 4 deletions benedict/serializers/ini.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from configparser import DEFAULTSECT as default_section
from configparser import RawConfigParser
from io import StringIO
from json.decoder import JSONDecodeError

from benedict.serializers.abstract import AbstractSerializer
from benedict.serializers.json import JSONSerializer
from benedict.utils import type_util


Expand All @@ -17,6 +19,7 @@ def __init__(self):
"ini",
],
)
self._json = JSONSerializer()

@staticmethod
def _get_parser(options):
Expand Down Expand Up @@ -49,9 +52,14 @@ def decode(self, s, **kwargs):
for section in parser.sections():
data[section] = {}
for option, _ in parser.items(section):
data[section][option] = self._get_section_option_value(
parser, section, option
)
value = self._get_section_option_value(parser, section, option)
if type_util.is_string(value):
try:
value_decoded = self._json.decode(value)
value = value_decoded
except JSONDecodeError:
pass
data[section][option] = value
return data

def encode(self, d, **kwargs):
Expand All @@ -63,7 +71,10 @@ def encode(self, d, **kwargs):
section = key
parser.add_section(section)
for option_key, option_value in value.items():
parser.set(section, option_key, f"{option_value}")
if type_util.is_collection(option_value):
parser.set(section, option_key, self._json.encode(option_value))
else:
parser.set(section, option_key, option_value)
str_data = StringIO()
parser.write(str_data)
return str_data.getvalue()
36 changes: 36 additions & 0 deletions tests/github/test_issue_0284.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import unittest

from benedict import benedict


class github_issue_0284_test_case(unittest.TestCase):
"""
This class describes a github issue 0284 test case.
https://github.com/fabiocaccamo/python-benedict/issues/284
To run this specific test:
- Run python -m unittest tests.github.test_issue_0284
"""

def test_from_ini_returns_str_instead_of_dict(self):
original = benedict(
{
"section1": {
"key1": "value1",
},
"sectionA": {
"keyA": "valueA",
"keyB": "valueB",
"keyC": {
"subkeyC": "subvalueC",
},
},
}
)
readback = benedict.from_ini(original.to_ini())
keypath = "sectionA.keyC"
# print("original vs readback")
# print(original.get(keypath), type(original.get(keypath)))
# print("-- vs --")
# print(readback.get(keypath), type(readback.get(keypath)))
self.assertEqual(original.get(keypath), readback.get(keypath))

0 comments on commit 84fa1c8

Please sign in to comment.