Skip to content

Commit 332638d

Browse files
committed
Allow ini format to support nested structures.
1 parent 9e07e48 commit 332638d

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

benedict/serializers/ini.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from configparser import DEFAULTSECT as default_section
22
from configparser import RawConfigParser
33
from io import StringIO
4+
from json.decoder import JSONDecodeError
45

56
from benedict.serializers.abstract import AbstractSerializer
7+
from benedict.serializers.json import JSONSerializer
68
from benedict.utils import type_util
79

810

@@ -17,6 +19,7 @@ def __init__(self):
1719
"ini",
1820
],
1921
)
22+
self._json = JSONSerializer()
2023

2124
@staticmethod
2225
def _get_parser(options):
@@ -49,9 +52,14 @@ def decode(self, s, **kwargs):
4952
for section in parser.sections():
5053
data[section] = {}
5154
for option, _ in parser.items(section):
52-
data[section][option] = self._get_section_option_value(
53-
parser, section, option
54-
)
55+
value = self._get_section_option_value(parser, section, option)
56+
if type_util.is_string(value):
57+
try:
58+
value_decoded = self._json.decode(value)
59+
value = value_decoded
60+
except JSONDecodeError:
61+
pass
62+
data[section][option] = value
5563
return data
5664

5765
def encode(self, d, **kwargs):
@@ -63,7 +71,10 @@ def encode(self, d, **kwargs):
6371
section = key
6472
parser.add_section(section)
6573
for option_key, option_value in value.items():
66-
parser.set(section, option_key, f"{option_value}")
74+
if type_util.is_collection(option_value):
75+
parser.set(section, option_key, self._json.encode(option_value))
76+
else:
77+
parser.set(section, option_key, option_value)
6778
str_data = StringIO()
6879
parser.write(str_data)
6980
return str_data.getvalue()

tests/github/test_issue_0284.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import unittest
2+
3+
from benedict import benedict
4+
5+
6+
class github_issue_0284_test_case(unittest.TestCase):
7+
"""
8+
This class describes a github issue 0284 test case.
9+
https://github.com/fabiocaccamo/python-benedict/issues/284
10+
11+
To run this specific test:
12+
- Run python -m unittest tests.github.test_issue_0284
13+
"""
14+
15+
def test_from_ini_returns_str_instead_of_dict(self):
16+
original = benedict(
17+
{
18+
"section1": {
19+
"key1": "value1",
20+
},
21+
"sectionA": {
22+
"keyA": "valueA",
23+
"keyB": "valueB",
24+
"keyC": {
25+
"subkeyC": "subvalueC",
26+
},
27+
},
28+
}
29+
)
30+
readback = benedict.from_ini(original.to_ini())
31+
keypath = "sectionA.keyC"
32+
# print("original vs readback")
33+
# print(original.get(keypath), type(original.get(keypath)))
34+
# print("-- vs --")
35+
# print(readback.get(keypath), type(readback.get(keypath)))
36+
self.assertEqual(original.get(keypath), readback.get(keypath))

0 commit comments

Comments
 (0)