| import datetime as _datetime |
| |
| from collections.abc import Mapping |
| from typing import IO |
| from typing import Iterable |
| from typing import Tuple |
| from typing import Union |
| |
| from ._utils import parse_rfc3339 |
| from .container import Container |
| from .exceptions import UnexpectedCharError |
| from .items import AoT |
| from .items import Array |
| from .items import Bool |
| from .items import Comment |
| from .items import Date |
| from .items import DateTime |
| from .items import DottedKey |
| from .items import Float |
| from .items import InlineTable |
| from .items import Integer |
| from .items import Item as _Item |
| from .items import Key |
| from .items import SingleKey |
| from .items import String |
| from .items import Table |
| from .items import Time |
| from .items import Trivia |
| from .items import Whitespace |
| from .items import item |
| from .parser import Parser |
| from .toml_document import TOMLDocument |
| |
| |
| def loads(string: Union[str, bytes]) -> TOMLDocument: |
| """ |
| Parses a string into a TOMLDocument. |
| |
| Alias for parse(). |
| """ |
| return parse(string) |
| |
| |
| def dumps(data: Mapping, sort_keys: bool = False) -> str: |
| """ |
| Dumps a TOMLDocument into a string. |
| """ |
| if not isinstance(data, Container) and isinstance(data, Mapping): |
| data = item(dict(data), _sort_keys=sort_keys) |
| |
| try: |
| # data should be a `Container` (and therefore implement `as_string`) |
| # for all type safe invocations of this function |
| return data.as_string() # type: ignore[attr-defined] |
| except AttributeError as ex: |
| msg = f"Expecting Mapping or TOML Container, {type(data)} given" |
| raise TypeError(msg) from ex |
| |
| |
| def load(fp: IO) -> TOMLDocument: |
| """ |
| Load toml document from a file-like object. |
| """ |
| return parse(fp.read()) |
| |
| |
| def dump(data: Mapping, fp: IO[str], *, sort_keys: bool = False) -> None: |
| """ |
| Dump a TOMLDocument into a writable file stream. |
| |
| :param data: a dict-like object to dump |
| :param sort_keys: if true, sort the keys in alphabetic order |
| """ |
| fp.write(dumps(data, sort_keys=sort_keys)) |
| |
| |
| def parse(string: Union[str, bytes]) -> TOMLDocument: |
| """ |
| Parses a string or bytes into a TOMLDocument. |
| """ |
| return Parser(string).parse() |
| |
| |
| def document() -> TOMLDocument: |
| """ |
| Returns a new TOMLDocument instance. |
| """ |
| return TOMLDocument() |
| |
| |
| # Items |
| def integer(raw: Union[str, int]) -> Integer: |
| """Create an integer item from a number or string.""" |
| return item(int(raw)) |
| |
| |
| def float_(raw: Union[str, float]) -> Float: |
| """Create an float item from a number or string.""" |
| return item(float(raw)) |
| |
| |
| def boolean(raw: str) -> Bool: |
| """Turn `true` or `false` into a boolean item.""" |
| return item(raw == "true") |
| |
| |
| def string(raw: str) -> String: |
| """Create a string item.""" |
| return item(raw) |
| |
| |
| def date(raw: str) -> Date: |
| """Create a TOML date.""" |
| value = parse_rfc3339(raw) |
| if not isinstance(value, _datetime.date): |
| raise ValueError("date() only accepts date strings.") |
| |
| return item(value) |
| |
| |
| def time(raw: str) -> Time: |
| """Create a TOML time.""" |
| value = parse_rfc3339(raw) |
| if not isinstance(value, _datetime.time): |
| raise ValueError("time() only accepts time strings.") |
| |
| return item(value) |
| |
| |
| def datetime(raw: str) -> DateTime: |
| """Create a TOML datetime.""" |
| value = parse_rfc3339(raw) |
| if not isinstance(value, _datetime.datetime): |
| raise ValueError("datetime() only accepts datetime strings.") |
| |
| return item(value) |
| |
| |
| def array(raw: str = None) -> Array: |
| """Create an array item for its string representation. |
| |
| :Example: |
| |
| >>> array("[1, 2, 3]") # Create from a string |
| [1, 2, 3] |
| >>> a = array() |
| >>> a.extend([1, 2, 3]) # Create from a list |
| >>> a |
| [1, 2, 3] |
| """ |
| if raw is None: |
| raw = "[]" |
| |
| return value(raw) |
| |
| |
| def table(is_super_table: bool = False) -> Table: |
| """Create an empty table. |
| |
| :param is_super_table: if true, the table is a super table |
| |
| :Example: |
| |
| >>> doc = document() |
| >>> foo = table(True) |
| >>> bar = table() |
| >>> bar.update({'x': 1}) |
| >>> foo.append('bar', bar) |
| >>> doc.append('foo', foo) |
| >>> print(doc.as_string()) |
| [foo.bar] |
| x = 1 |
| """ |
| return Table(Container(), Trivia(), False, is_super_table) |
| |
| |
| def inline_table() -> InlineTable: |
| """Create an inline table. |
| |
| :Example: |
| |
| >>> table = inline_table() |
| >>> table.update({'x': 1, 'y': 2}) |
| >>> print(table.as_string()) |
| {x = 1, y = 2} |
| """ |
| return InlineTable(Container(), Trivia(), new=True) |
| |
| |
| def aot() -> AoT: |
| """Create an array of table. |
| |
| :Example: |
| |
| >>> doc = document() |
| >>> aot = aot() |
| >>> aot.append(item({'x': 1})) |
| >>> doc.append('foo', aot) |
| >>> print(doc.as_string()) |
| [[foo]] |
| x = 1 |
| """ |
| return AoT([]) |
| |
| |
| def key(k: Union[str, Iterable[str]]) -> Key: |
| """Create a key from a string. When a list of string is given, |
| it will create a dotted key. |
| |
| :Example: |
| |
| >>> doc = document() |
| >>> doc.append(key('foo'), 1) |
| >>> doc.append(key(['bar', 'baz']), 2) |
| >>> print(doc.as_string()) |
| foo = 1 |
| bar.baz = 2 |
| """ |
| if isinstance(k, str): |
| return SingleKey(k) |
| return DottedKey([key(_k) for _k in k]) |
| |
| |
| def value(raw: str) -> _Item: |
| """Parse a simple value from a string. |
| |
| :Example: |
| |
| >>> value("1") |
| 1 |
| >>> value("true") |
| True |
| >>> value("[1, 2, 3]") |
| [1, 2, 3] |
| """ |
| parser = Parser(raw) |
| v = parser._parse_value() |
| if not parser.end(): |
| raise parser.parse_error(UnexpectedCharError, char=parser._current) |
| return v |
| |
| |
| def key_value(src: str) -> Tuple[Key, _Item]: |
| """Parse a key-value pair from a string. |
| |
| :Example: |
| |
| >>> key_value("foo = 1") |
| (Key('foo'), 1) |
| """ |
| return Parser(src)._parse_key_value() |
| |
| |
| def ws(src: str) -> Whitespace: |
| """Create a whitespace from a string.""" |
| return Whitespace(src, fixed=True) |
| |
| |
| def nl() -> Whitespace: |
| """Create a newline item.""" |
| return ws("\n") |
| |
| |
| def comment(string: str) -> Comment: |
| """Create a comment item.""" |
| return Comment(Trivia(comment_ws=" ", comment="# " + string)) |