Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow string type to be controlled from the public API #177

Merged
merged 7 commits into from Feb 14, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,10 @@
- Fix the only child detection when creating tables. ([#175](https://github.com/sdispater/tomlkit/issues/175))
- Include the `docs/` directory and `CHANGELOG.md` in sdist tarball. ([#176](https://github.com/sdispater/tomlkit/issues/176))

### Added

- Add keyword arguments to `string` API to allow selecting the representation type. ([#177](https://github.com/sdispater/tomlkit/pull/177))

## [0.9.2] - 2022-02-08

### Changed
Expand Down
20 changes: 20 additions & 0 deletions tests/test_api.py
Expand Up @@ -392,3 +392,23 @@ def test_create_super_table_with_table():
def test_create_super_table_with_aot():
data = {"foo": {"bar": [{"a": 1}]}}
assert dumps(data) == "[[foo.bar]]\na = 1\n"


@pytest.mark.parametrize(
"kwargs, example, expected",
[
({}, "My\nString\u0001", '"My\\nString\\u0001"'),
({"escape": False}, "My String\u0001", '"My String\u0001"'),
({"single_quotes": True}, "My\nString", "'My\\nString'"),
({"multiline": True}, "\nMy\nString\n", '"""\nMy\nString\n"""'),
({"multiline": True, "single_quotes": True}, "My\nString", "'''My\nString'''"),
(
{"multiline": True, "single_quotes": True, "escape": True},
"My\nString",
"'''My\\nString'''",
),
],
)
def test_create_string_with_different_types(kwargs, example, expected):
value = tomlkit.string(example, **kwargs)
assert value.as_string() == expected
22 changes: 19 additions & 3 deletions tomlkit/api.py
Expand Up @@ -23,6 +23,7 @@
from .items import Key
from .items import SingleKey
from .items import String
from .items import StringType as _StringType
from .items import Table
from .items import Time
from .items import Trivia
Expand Down Expand Up @@ -104,9 +105,24 @@ def boolean(raw: str) -> Bool:
return item(raw == "true")


def string(raw: str) -> String:
"""Create a string item."""
return item(raw)
def string(
raw: str,
*,
frostming marked this conversation as resolved.
Show resolved Hide resolved
single_quotes: bool = False,
frostming marked this conversation as resolved.
Show resolved Hide resolved
multiline: bool = False,
escape: Union[None, bool] = None,
) -> String:
"""Create a string item.

Boolean flags (e.g. ``single_quotes=True`` and/or ``multiline=True``)
can be used for personalization.

By default, single line strings are escaped, but multi line strings are not.
This can be controlled by explicitly setting ``escape``.
"""
escape = (not multiline) if escape is None else escape
type_ = _StringType.select(single_quotes, multiline)
return String.from_raw(raw, type_, escape)


def date(raw: str) -> Date:
Expand Down
19 changes: 16 additions & 3 deletions tomlkit/items.py
Expand Up @@ -124,9 +124,7 @@ def item(

return a
elif isinstance(value, str):
escaped = escape_string(value)

return String(StringType.SLB, decode(value), escaped, Trivia())
return String.from_raw(value, escape=True)
elif isinstance(value, datetime):
return DateTime(
value.year,
Expand Down Expand Up @@ -166,6 +164,15 @@ class StringType(Enum):
# Multi Line Literal
MLL = "'''"

@classmethod
def select(cls, single_quotes=False, multiline=False) -> "StringType":
return {
(False, False): cls.SLB,
(False, True): cls.MLB,
(True, False): cls.SLL,
(True, True): cls.MLL,
}[(single_quotes, multiline)]

@property
@lru_cache(maxsize=None)
def unit(self) -> str:
Expand Down Expand Up @@ -1512,6 +1519,12 @@ def _new(self, result):
def _getstate(self, protocol=3):
return self._t, str(self), self._original, self._trivia

@classmethod
def from_raw(cls, value: str, type_=StringType.SLB, escape=False) -> "String":
string_value = escape_string(value) if escape else value
frostming marked this conversation as resolved.
Show resolved Hide resolved

return cls(type_, decode(value), string_value, Trivia())


class AoT(Item, _CustomList):
"""
Expand Down