Skip to content

Commit 9cf42c6

Browse files
authored
fix: Build table with dotted key correctly (#284)
1 parent 2a3b2d1 commit 9cf42c6

File tree

11 files changed

+273
-306
lines changed

11 files changed

+273
-306
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/psf/black
3-
rev: 22.12.0
3+
rev: 23.3.0
44
hooks:
55
- id: black
66

@@ -37,7 +37,7 @@ repos:
3737
exclude: ^tomlkit/items\.py
3838

3939
- repo: https://github.com/asottile/pyupgrade
40-
rev: v3.3.1
40+
rev: v3.3.2
4141
hooks:
4242
- id: pyupgrade
4343
args: [--py37-plus]

pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
name = "tomlkit"
33
version = "0.11.7"
44
description = "Style preserving TOML library"
5-
authors = ["Sébastien Eustace <[email protected]>"]
5+
authors = [
6+
"Sébastien Eustace <[email protected]>",
7+
"Frost Ming <[email protected]>"
8+
]
69
license = "MIT"
710

811
readme = "README.md"

tests/test_toml_document.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,3 +1030,32 @@ def test_nested_table_update_display_name():
10301030
z = 3
10311031
"""
10321032
assert doc.as_string() == dedent(expected)
1033+
1034+
1035+
def test_build_table_with_dotted_key():
1036+
doc = tomlkit.document()
1037+
data = {
1038+
"a.b.c": 1,
1039+
"a.b.d": 2,
1040+
"a": {"c": {"foo": "bar"}},
1041+
"a.d.e": 3,
1042+
}
1043+
1044+
for key, value in data.items():
1045+
if "." not in key:
1046+
doc.append(key, value)
1047+
else:
1048+
doc.append(tomlkit.key(key.split(".")), value)
1049+
1050+
expected = """\
1051+
a.b.c = 1
1052+
a.b.d = 2
1053+
a.d.e = 3
1054+
1055+
[a.c]
1056+
foo = "bar"
1057+
"""
1058+
assert doc.as_string() == expected
1059+
assert json.loads(json.dumps(doc)) == {
1060+
"a": {"b": {"c": 1, "d": 2}, "d": {"e": 3}, "c": {"foo": "bar"}}
1061+
}

tomlkit/_compat.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1+
from __future__ import annotations
2+
13
import contextlib
24
import sys
35

46
from typing import Any
5-
from typing import List
6-
from typing import Optional
77

88

99
PY38 = sys.version_info >= (3, 8)
1010

1111

12-
def decode(string: Any, encodings: Optional[List[str]] = None):
12+
def decode(string: Any, encodings: list[str] | None = None):
1313
if not isinstance(string, bytes):
1414
return string
1515

tomlkit/_utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import re
24

35
from collections.abc import Mapping
@@ -7,7 +9,6 @@
79
from datetime import timedelta
810
from datetime import timezone
911
from typing import Collection
10-
from typing import Union
1112

1213
from tomlkit._compat import decode
1314

@@ -41,7 +42,7 @@
4142
_utc = timezone(timedelta(), "UTC")
4243

4344

44-
def parse_rfc3339(string: str) -> Union[datetime, date, time]:
45+
def parse_rfc3339(string: str) -> datetime | date | time:
4546
m = RFC_3339_DATETIME.match(string)
4647
if m:
4748
year = int(m.group(1))

tomlkit/api.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
from __future__ import annotations
2+
13
import datetime as _datetime
24

35
from collections.abc import Mapping
46
from typing import IO
57
from typing import Iterable
6-
from typing import Optional
7-
from typing import Tuple
8-
from typing import Union
98

109
from tomlkit._utils import parse_rfc3339
1110
from tomlkit.container import Container
@@ -34,7 +33,7 @@
3433
from tomlkit.toml_document import TOMLDocument
3534

3635

37-
def loads(string: Union[str, bytes]) -> TOMLDocument:
36+
def loads(string: str | bytes) -> TOMLDocument:
3837
"""
3938
Parses a string into a TOMLDocument.
4039
@@ -59,7 +58,7 @@ def dumps(data: Mapping, sort_keys: bool = False) -> str:
5958
raise TypeError(msg) from ex
6059

6160

62-
def load(fp: Union[IO[str], IO[bytes]]) -> TOMLDocument:
61+
def load(fp: IO[str] | IO[bytes]) -> TOMLDocument:
6362
"""
6463
Load toml document from a file-like object.
6564
"""
@@ -76,7 +75,7 @@ def dump(data: Mapping, fp: IO[str], *, sort_keys: bool = False) -> None:
7675
fp.write(dumps(data, sort_keys=sort_keys))
7776

7877

79-
def parse(string: Union[str, bytes]) -> TOMLDocument:
78+
def parse(string: str | bytes) -> TOMLDocument:
8079
"""
8180
Parses a string or bytes into a TOMLDocument.
8281
"""
@@ -91,12 +90,12 @@ def document() -> TOMLDocument:
9190

9291

9392
# Items
94-
def integer(raw: Union[str, int]) -> Integer:
93+
def integer(raw: str | int) -> Integer:
9594
"""Create an integer item from a number or string."""
9695
return item(int(raw))
9796

9897

99-
def float_(raw: Union[str, float]) -> Float:
98+
def float_(raw: str | float) -> Float:
10099
"""Create an float item from a number or string."""
101100
return item(float(raw))
102101

@@ -175,7 +174,7 @@ def array(raw: str = None) -> Array:
175174
return value(raw)
176175

177176

178-
def table(is_super_table: Optional[bool] = None) -> Table:
177+
def table(is_super_table: bool | None = None) -> Table:
179178
"""Create an empty table.
180179
181180
:param is_super_table: if true, the table is a super table
@@ -224,7 +223,7 @@ def aot() -> AoT:
224223
return AoT([])
225224

226225

227-
def key(k: Union[str, Iterable[str]]) -> Key:
226+
def key(k: str | Iterable[str]) -> Key:
228227
"""Create a key from a string. When a list of string is given,
229228
it will create a dotted key.
230229
@@ -261,7 +260,7 @@ def value(raw: str) -> _Item:
261260
return v
262261

263262

264-
def key_value(src: str) -> Tuple[Key, _Item]:
263+
def key_value(src: str) -> tuple[Key, _Item]:
265264
"""Parse a key-value pair from a string.
266265
267266
:Example:

0 commit comments

Comments
 (0)