| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- from __future__ import annotations
- import contextlib
- import datetime as _datetime
- from collections.abc import Mapping
- from typing import IO
- from typing import Iterable
- from typing import TypeVar
- from tomlkit._utils import parse_rfc3339
- from tomlkit.container import Container
- from tomlkit.exceptions import UnexpectedCharError
- from tomlkit.items import CUSTOM_ENCODERS
- from tomlkit.items import AoT
- from tomlkit.items import Array
- from tomlkit.items import Bool
- from tomlkit.items import Comment
- from tomlkit.items import Date
- from tomlkit.items import DateTime
- from tomlkit.items import DottedKey
- from tomlkit.items import Encoder
- from tomlkit.items import Float
- from tomlkit.items import InlineTable
- from tomlkit.items import Integer
- from tomlkit.items import Item as _Item
- from tomlkit.items import Key
- from tomlkit.items import SingleKey
- from tomlkit.items import String
- from tomlkit.items import StringType as _StringType
- from tomlkit.items import Table
- from tomlkit.items import Time
- from tomlkit.items import Trivia
- from tomlkit.items import Whitespace
- from tomlkit.items import item
- from tomlkit.parser import Parser
- from tomlkit.toml_document import TOMLDocument
- def loads(string: 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[str] | IO[bytes]) -> 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: 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: str | int) -> Integer:
- """Create an integer item from a number or string."""
- return item(int(raw))
- def float_(raw: 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,
- *,
- literal: bool = False,
- multiline: bool = False,
- escape: bool = True,
- ) -> String:
- """Create a string item.
- By default, this function will create *single line basic* strings, but
- boolean flags (e.g. ``literal=True`` and/or ``multiline=True``)
- can be used for personalization.
- For more information, please check the spec: `<https://toml.io/en/v1.0.0#string>`__.
- Common escaping rules will be applied for basic strings.
- This can be controlled by explicitly setting ``escape=False``.
- Please note that, if you disable escaping, you will have to make sure that
- the given strings don't contain any forbidden character or sequence.
- """
- type_ = _StringType.select(literal, multiline)
- return String.from_raw(raw, type_, escape)
- 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 | None = None) -> 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: 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))
- E = TypeVar("E", bound=Encoder)
- def register_encoder(encoder: E) -> E:
- """Add a custom encoder, which should be a function that will be called
- if the value can't otherwise be converted. It should takes a single value
- and return a TOMLKit item or raise a ``TypeError``.
- """
- CUSTOM_ENCODERS.append(encoder)
- return encoder
- def unregister_encoder(encoder: Encoder) -> None:
- """Unregister a custom encoder."""
- with contextlib.suppress(ValueError):
- CUSTOM_ENCODERS.remove(encoder)
|