Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions benedict/serializers/ini.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

from collections.abc import Callable
from configparser import DEFAULTSECT as default_section
from configparser import RawConfigParser
from io import StringIO
from json.decoder import JSONDecodeError
Expand Down Expand Up @@ -58,7 +57,7 @@ def decode(self, s: str, **kwargs: Any) -> dict[str, Any]:
data: dict[str, Any] = {}
for option, _ in parser.defaults().items():
data[option] = self._get_section_option_value(
parser, default_section, option
parser, parser.default_section, option
)
for section in parser.sections():
data[section] = {}
Expand All @@ -77,7 +76,9 @@ def encode(self, d: dict[str, Any], **kwargs: Any) -> str:
parser = self._get_parser(options=kwargs)
for key, value in d.items():
if not type_util.is_dict(value):
parser.set(default_section, key, None if value is None else f"{value}")
parser.set(
parser.default_section, key, None if value is None else f"{value}"
)
continue
section = key
parser.add_section(section)
Expand Down
52 changes: 52 additions & 0 deletions tests/dicts/io/test_io_dict_ini.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,58 @@ class io_dict_ini_test_case(io_dict_test_case):
This class describes an IODict / ini test case.
"""

def test_from_ini_with_custom_default_section(self) -> None:
s = (
"[general]\ncount = 2\nratio = 1.5\nenabled = yes\nname = demo\n"
"[app]\ncount = 3\n"
)
expected = {
"count": 2,
"ratio": 1.5,
"enabled": True,
"name": "demo",
"app": {"count": 3, "ratio": 1.5, "enabled": True, "name": "demo"},
}
self.assertEqual(IODict.from_ini(s, default_section="general"), expected)
self.assertEqual(IODict(s, format="ini", default_section="general"), expected)

def test_from_ini_with_custom_defaults_and_literal_default_section(self) -> None:
s = "[general]\ncount = 2\n[DEFAULT]\ncount = 9\n[app]\nname = demo\n"
expected = {
"count": 2,
"DEFAULT": {"count": 9},
"app": {"count": 2, "name": "demo"},
}
self.assertEqual(IODict.from_ini(s, default_section="general"), expected)

def test_from_ini_with_custom_valueless_defaults(self) -> None:
s = "[general]\nflag\n[app]\nname = demo\n"
expected = {"flag": None, "app": {"flag": None, "name": "demo"}}
self.assertEqual(
IODict.from_ini(s, default_section="general", allow_no_value=True),
expected,
)

def test_to_ini_with_custom_default_section(self) -> None:
for value, line, options in (
(2, "count = 2", {}),
(None, "count", {"allow_no_value": True}),
):
with self.subTest(value=value):
d = IODict({"count": value, "app": {"name": "demo"}})
s = d.to_ini(default_section="general", **options)
self.assertEqual(s, f"[general]\n{line}\n\n[app]\nname = demo\n\n")
self.assertEqual(
IODict.from_ini(s, default_section="general", **options),
{"count": value, "app": {"count": value, "name": "demo"}},
)

def test_to_ini_with_custom_defaults_and_literal_default_section(self) -> None:
d = IODict({"DEFAULT": {"count": 9}, "count": 2})
s = d.to_ini(default_section="general")
self.assertEqual(s, "[general]\ncount = 2\n\n[DEFAULT]\ncount = 9\n\n")
self.assertEqual(IODict.from_ini(s, default_section="general"), d)

def test_from_ini_with_valueless_options(self) -> None:
s = "[app]\nflag\nempty =\ncount = 2\nratio = 1.5\nenabled = yes\n"
expected = {
Expand Down
Loading