Skip to content

Commit 7f237d8

Browse files
authored
feat(spec): update to toml spec v1.1 (#456)
* feat(spec): update to toml spec v1.1 Signed-off-by: Frost Ming <me@frostming.com> * feat(changelog): update parser to support TOML spec v1.1.0 Signed-off-by: Frost Ming <me@frostming.com>
1 parent 090a28e commit 7f237d8

File tree

340 files changed

+276
-7548
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

340 files changed

+276
-7548
lines changed

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
[submodule "tests/toml-test"]
22
path = tests/toml-test
33
url = https://github.com/BurntSushi/toml-test.git
4-
[submodule "tests/toml-spec-tests"]
5-
path = tests/toml-spec-tests
6-
url = https://github.com/iarna/toml-spec-tests.git

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Change Log
22

3+
## [unreleased]
4+
5+
### Changed
6+
7+
- Update parser to support TOML spec v1.1.0. ([#456](https://github.com/python-poetry/tomlkit/pull/456)
8+
39
## [0.14.0] - 2026-01-13
410

511
### Changed

tests/conftest.py

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -39,67 +39,3 @@ def _example(name):
3939
return f.read()
4040

4141
return _example
42-
43-
44-
TEST_DIR = os.path.join(os.path.dirname(__file__), "toml-test", "tests")
45-
IGNORED_TESTS = {
46-
"valid": [
47-
"float/inf-and-nan", # Can't compare nan
48-
]
49-
}
50-
51-
52-
def get_tomltest_cases():
53-
dirs = sorted(
54-
f for f in os.listdir(TEST_DIR) if os.path.isdir(os.path.join(TEST_DIR, f))
55-
)
56-
assert dirs == ["invalid", "valid"]
57-
rv = {"invalid_encode": {}}
58-
for d in dirs:
59-
rv[d] = {}
60-
ignored = IGNORED_TESTS.get(d, [])
61-
62-
for root, _, files in os.walk(os.path.join(TEST_DIR, d)):
63-
relpath = os.path.relpath(root, os.path.join(TEST_DIR, d))
64-
if relpath == ".":
65-
relpath = ""
66-
for f in files:
67-
try:
68-
bn, ext = f.rsplit(".", 1)
69-
except ValueError:
70-
bn, ext = f.rsplit("-", 1)
71-
key = f"{relpath}/{bn}"
72-
if ext == "multi":
73-
continue
74-
if key in ignored:
75-
continue
76-
if d == "invalid" and relpath == "encoding":
77-
rv["invalid_encode"][bn] = os.path.join(root, f)
78-
continue
79-
if key not in rv[d]:
80-
rv[d][key] = {}
81-
with open(os.path.join(root, f), encoding="utf-8") as inp:
82-
rv[d][key][ext] = inp.read()
83-
return rv
84-
85-
86-
def pytest_generate_tests(metafunc):
87-
test_list = get_tomltest_cases()
88-
if "valid_case" in metafunc.fixturenames:
89-
metafunc.parametrize(
90-
"valid_case",
91-
test_list["valid"].values(),
92-
ids=list(test_list["valid"].keys()),
93-
)
94-
elif "invalid_decode_case" in metafunc.fixturenames:
95-
metafunc.parametrize(
96-
"invalid_decode_case",
97-
test_list["invalid"].values(),
98-
ids=list(test_list["invalid"].keys()),
99-
)
100-
elif "invalid_encode_case" in metafunc.fixturenames:
101-
metafunc.parametrize(
102-
"invalid_encode_case",
103-
test_list["invalid_encode"].values(),
104-
ids=list(test_list["invalid_encode"].keys()),
105-
)

tests/test_api.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ def test_parsed_document_are_properly_json_representable(
120120
("inline_table_no_comma", UnexpectedCharError),
121121
("inline_table_duplicate_comma", UnexpectedCharError),
122122
("inline_table_leading_comma", UnexpectedCharError),
123-
("inline_table_trailing_comma", UnexpectedCharError),
124123
],
125124
)
126125
def test_parse_raises_errors_for_invalid_toml_files(

tests/test_toml_spec_tests.py

Lines changed: 0 additions & 111 deletions
This file was deleted.

tests/test_toml_tests.py

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import os
23

34
import pytest
45

@@ -9,6 +10,10 @@
910
from tomlkit.exceptions import TOMLKitError
1011

1112

13+
TESTS_ROOT = os.path.join(os.path.dirname(__file__), "toml-test", "tests")
14+
FILES_LIST = os.path.join(TESTS_ROOT, "files-toml-1.1.0")
15+
16+
1217
def to_bool(s):
1318
assert s in ["true", "false"]
1419

@@ -43,20 +48,87 @@ def untag(value):
4348
return {k: untag(v) for k, v in value.items()}
4449

4550

46-
def test_valid_decode(valid_case):
47-
json_val = untag(json.loads(valid_case["json"]))
48-
toml_val = parse(valid_case["toml"])
51+
def _load_case_list():
52+
with open(FILES_LIST, encoding="utf-8") as f:
53+
return [line.strip() for line in f if line.strip()]
54+
55+
56+
def _build_cases():
57+
valid_cases = []
58+
valid_ids = []
59+
invalid_decode_cases = []
60+
invalid_decode_ids = []
61+
invalid_encode_cases = []
62+
invalid_encode_ids = []
63+
64+
for relpath in _load_case_list():
65+
full_path = os.path.join(TESTS_ROOT, relpath)
66+
if not relpath.endswith(".toml"):
67+
continue
68+
69+
case_id = relpath.rsplit(".", 1)[0]
70+
71+
if relpath.startswith("invalid/encoding/"):
72+
invalid_encode_cases.append(full_path)
73+
invalid_encode_ids.append(case_id)
74+
elif relpath.startswith("valid/"):
75+
with open(full_path, encoding="utf-8", newline="") as f:
76+
toml_content = f.read()
77+
78+
json_path = full_path.rsplit(".", 1)[0] + ".json"
79+
with open(json_path, encoding="utf-8") as f:
80+
json_content = f.read()
81+
82+
valid_cases.append({"toml": toml_content, "json": json_content})
83+
valid_ids.append(case_id)
84+
elif relpath.startswith("invalid/"):
85+
with open(full_path, encoding="utf-8", newline="") as f:
86+
toml_content = f.read()
87+
88+
invalid_decode_cases.append({"toml": toml_content})
89+
invalid_decode_ids.append(case_id)
90+
91+
return (
92+
valid_cases,
93+
valid_ids,
94+
invalid_decode_cases,
95+
invalid_decode_ids,
96+
invalid_encode_cases,
97+
invalid_encode_ids,
98+
)
99+
100+
101+
(
102+
VALID_CASES,
103+
VALID_IDS,
104+
INVALID_DECODE_CASES,
105+
INVALID_DECODE_IDS,
106+
INVALID_ENCODE_CASES,
107+
INVALID_ENCODE_IDS,
108+
) = _build_cases()
109+
110+
111+
@pytest.mark.parametrize("toml11_valid_case", VALID_CASES, ids=VALID_IDS)
112+
def test_valid_decode(toml11_valid_case):
113+
json_val = untag(json.loads(toml11_valid_case["json"]))
114+
toml_val = parse(toml11_valid_case["toml"])
49115

50116
assert toml_val == json_val
51-
assert toml_val.as_string() == valid_case["toml"]
117+
assert toml_val.as_string() == toml11_valid_case["toml"]
52118

53119

54-
def test_invalid_decode(invalid_decode_case):
120+
@pytest.mark.parametrize(
121+
"toml11_invalid_decode_case", INVALID_DECODE_CASES, ids=INVALID_DECODE_IDS
122+
)
123+
def test_invalid_decode(toml11_invalid_decode_case):
55124
with pytest.raises(TOMLKitError):
56-
parse(invalid_decode_case["toml"])
125+
parse(toml11_invalid_decode_case["toml"])
57126

58127

59-
def test_invalid_encode(invalid_encode_case):
60-
with open(invalid_encode_case, encoding="utf-8") as f:
128+
@pytest.mark.parametrize(
129+
"toml11_invalid_encode_case", INVALID_ENCODE_CASES, ids=INVALID_ENCODE_IDS
130+
)
131+
def test_invalid_encode(toml11_invalid_encode_case):
132+
with open(toml11_invalid_encode_case, encoding="utf-8") as f:
61133
with pytest.raises((TOMLKitError, UnicodeDecodeError)):
62134
load(f)

tests/toml-spec-tests/.gitattributes

Lines changed: 0 additions & 3 deletions
This file was deleted.

tests/toml-spec-tests/LICENSE

Lines changed: 0 additions & 14 deletions
This file was deleted.

tests/toml-spec-tests/README.md

Lines changed: 0 additions & 14 deletions
This file was deleted.

tests/toml-spec-tests/errors/array-of-tables-1.toml

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)