1
|
2
|
from datetime import date, datetime, time, timezone
|
2
|
2
|
from io import TextIOBase
|
3
|
2
|
from pathlib import Path
|
4
|
2
|
from typing import Any, TextIO, Union
|
5
|
|
|
6
|
2
|
from . import _rtoml
|
7
|
|
|
8
|
2
|
__all__ = 'VERSION', 'TomlParsingError', 'TomlSerializationError', 'load', 'loads', 'dumps', 'dump'
|
9
|
|
|
10
|
|
# VERSION is set in Cargo.toml
|
11
|
2
|
VERSION = _rtoml.VERSION
|
12
|
2
|
TomlParsingError = _rtoml.TomlParsingError
|
13
|
2
|
TomlSerializationError = _rtoml.TomlSerializationError
|
14
|
|
|
15
|
|
|
16
|
2
|
def load(toml: Union[str, Path, TextIO]) -> Any:
|
17
|
|
"""
|
18
|
|
Parse TOML via a string or file and return a python object. The `toml` argument may be a `str`,
|
19
|
|
`Path` or file object from `open()`.
|
20
|
|
"""
|
21
|
2
|
if isinstance(toml, Path):
|
22
|
2
|
toml = toml.read_text()
|
23
|
2
|
elif isinstance(toml, (TextIOBase, TextIO)):
|
24
|
2
|
toml = toml.read()
|
25
|
|
|
26
|
2
|
return loads(toml)
|
27
|
|
|
28
|
|
|
29
|
2
|
def loads(toml: str) -> Any:
|
30
|
|
"""
|
31
|
|
Parse a TOML string and return a python object. (provided to match the interface of `json` and similar libraries)
|
32
|
|
"""
|
33
|
2
|
if not isinstance(toml, str):
|
34
|
2
|
raise TypeError(f'invalid toml input, must be str not {type(toml)}')
|
35
|
2
|
return _rtoml.deserialize(toml, parse_datetime)
|
36
|
|
|
37
|
|
|
38
|
2
|
def dumps(obj: Any) -> str:
|
39
|
|
"""
|
40
|
|
Serialize a python object to TOML.
|
41
|
|
"""
|
42
|
2
|
return _rtoml.serialize(obj)
|
43
|
|
|
44
|
|
|
45
|
2
|
def dump(obj: Any, file: Union[Path, TextIO]) -> int:
|
46
|
|
"""
|
47
|
|
Serialize a python object to TOML and write it to a file. `file` may be a `Path` or file object from `open()`.
|
48
|
|
"""
|
49
|
2
|
s = dumps(obj)
|
50
|
2
|
if isinstance(file, Path):
|
51
|
2
|
return file.write_text(s)
|
52
|
|
else:
|
53
|
2
|
return file.write(s)
|
54
|
|
|
55
|
|
|
56
|
2
|
def parse_datetime(v: str) -> Union[date, time]:
|
57
|
2
|
try:
|
58
|
2
|
return date.fromisoformat(v)
|
59
|
2
|
except ValueError:
|
60
|
2
|
tz = None
|
61
|
2
|
if v.endswith(('z', 'Z')):
|
62
|
2
|
tz = timezone.utc
|
63
|
2
|
v = v[:-1]
|
64
|
2
|
try:
|
65
|
2
|
dt = datetime.fromisoformat(v)
|
66
|
2
|
except ValueError:
|
67
|
2
|
return time.fromisoformat(v)
|
68
|
|
else:
|
69
|
2
|
if tz:
|
70
|
2
|
dt = dt.replace(tzinfo=tz)
|
71
|
2
|
return dt
|