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
44 changes: 44 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,50 @@ def test_key_value() -> None:
assert isinstance(i, Integer)


@pytest.mark.parametrize(
"src",
["foo = 12", "foo = 12\n", " foo = 12", "foo = 12 ", "foo = 12 # comment\n"],
)
def test_key_value_allows_trailing_whitespace_and_comment(src: str) -> None:
k, i = tomlkit.key_value(src)

assert k.key == "foo"
assert i == 12


@pytest.mark.parametrize(
"src",
[
"foo = 12 junk",
"foo = 12 = 13",
"foo = 12]]]",
],
)
def test_key_value_raises_on_trailing_chars(src: str) -> None:
# parse() rejects each of these; key_value() must agree.
with pytest.raises(UnexpectedCharError):
parse(src)

with pytest.raises(UnexpectedCharError):
tomlkit.key_value(src)


def test_key_value_raises_on_a_second_pair() -> None:
# Two pairs are a valid document, but key_value() parses a single pair,
# so the second one is trailing input rather than a silently dropped value.
assert dict(parse("foo = 12\nbar = 13")) == {"foo": 12, "bar": 13}

with pytest.raises(UnexpectedCharError):
tomlkit.key_value("foo = 12\nbar = 13")


def test_key_value_raises_on_invalid_example(
invalid_example: Callable[[str], str],
) -> None:
with pytest.raises(UnexpectedCharError):
tomlkit.key_value(invalid_example("key_value_with_trailing_chars"))


def test_string() -> None:
s = tomlkit.string('foo "')

Expand Down
9 changes: 8 additions & 1 deletion tomlkit/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,19 @@ def value(raw: str) -> _Item:
def key_value(src: str) -> tuple[Key, _Item]:
"""Parse a key-value pair from a string.

Anything other than whitespace or a comment after the pair is an error,
as it is when the same text is given to :func:`parse`.

:Example:

>>> key_value("foo = 1")
(Key('foo'), 1)
"""
return Parser(src)._parse_key_value()
parser = Parser(src)
k, v = parser._parse_key_value(parse_comment=True)
if not parser.end():
raise parser.parse_error(UnexpectedCharError, char=parser._current)
return k, v


def ws(src: str) -> Whitespace:
Expand Down