Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/msgspec/toml.py: 33%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from __future__ import annotations
3import datetime as _datetime
4from typing import TYPE_CHECKING, Any, TypeVar, overload
6from . import (
7 DecodeError as _DecodeError,
8 convert as _convert,
9 to_builtins as _to_builtins,
10)
12if TYPE_CHECKING:
13 from typing import Callable, Literal, Optional, Type, Union
15 from typing_extensions import Buffer
18__all__ = ("encode", "decode")
21def __dir__():
22 return __all__
25def _import_tomllib():
26 try:
27 import tomllib # type: ignore
29 return tomllib
30 except ImportError:
31 pass
33 try:
34 import tomli # type: ignore
36 return tomli
37 except ImportError:
38 raise ImportError(
39 "`msgspec.toml.decode` requires `tomli` be installed.\n\n"
40 "Please either `pip` or `conda` install it as follows:\n\n"
41 " $ python -m pip install tomli # using pip\n"
42 " $ conda install tomli # or using conda"
43 ) from None
46def _import_tomli_w():
47 try:
48 import tomli_w # type: ignore
50 return tomli_w
51 except ImportError:
52 raise ImportError(
53 "`msgspec.toml.encode` requires `tomli_w` be installed.\n\n"
54 "Please either `pip` or `conda` install it as follows:\n\n"
55 " $ python -m pip install tomli_w # using pip\n"
56 " $ conda install tomli_w # or using conda"
57 ) from None
60def encode(
61 obj: Any,
62 *,
63 enc_hook: Optional[Callable[[Any], Any]] = None,
64 order: Literal[None, "deterministic", "sorted"] = None,
65) -> bytes:
66 """Serialize an object as TOML.
68 Parameters
69 ----------
70 obj : Any
71 The object to serialize.
72 enc_hook : callable, optional
73 A callable to call for objects that aren't supported msgspec types.
74 Takes the unsupported object and should return a supported object, or
75 raise a ``NotImplementedError`` if unsupported.
76 order : {None, 'deterministic', 'sorted'}, optional
77 The ordering to use when encoding unordered compound types.
79 - ``None``: All objects are encoded in the most efficient manner
80 matching their in-memory representations. The default.
81 - `'deterministic'`: Unordered collections (sets, dicts) are sorted to
82 ensure a consistent output between runs. Useful when
83 comparison/hashing of the encoded binary output is necessary.
84 - `'sorted'`: Like `'deterministic'`, but *all* object-like types
85 (structs, dataclasses, ...) are also sorted by field name before
86 encoding. This is slower than `'deterministic'`, but may produce more
87 human-readable output.
89 Returns
90 -------
91 data : bytes
92 The serialized object.
94 See Also
95 --------
96 decode
97 """
98 toml = _import_tomli_w()
99 msg = _to_builtins(
100 obj,
101 builtin_types=(_datetime.datetime, _datetime.date, _datetime.time),
102 str_keys=True,
103 enc_hook=enc_hook,
104 order=order,
105 )
106 return toml.dumps(msg).encode("utf-8")
109T = TypeVar("T")
112@overload
113def decode(
114 buf: Union[Buffer, str],
115 *,
116 strict: bool = True,
117 dec_hook: Optional[Callable[[type, Any], Any]] = None,
118) -> Any:
119 pass
122@overload
123def decode(
124 buf: Union[Buffer, str],
125 *,
126 type: Type[T] = ...,
127 strict: bool = True,
128 dec_hook: Optional[Callable[[type, Any], Any]] = None,
129) -> T:
130 pass
133@overload
134def decode(
135 buf: Union[Buffer, str],
136 *,
137 type: Any = ...,
138 strict: bool = True,
139 dec_hook: Optional[Callable[[type, Any], Any]] = None,
140) -> Any:
141 pass
144def decode(buf, *, type=Any, strict=True, dec_hook=None):
145 """Deserialize an object from TOML.
147 Parameters
148 ----------
149 buf : bytes-like or str
150 The message to decode.
151 type : type, optional
152 A Python type (in type annotation form) to decode the object as. If
153 provided, the message will be type checked and decoded as the specified
154 type. Defaults to `Any`, in which case the message will be decoded
155 using the default TOML types.
156 strict : bool, optional
157 Whether type coercion rules should be strict. Setting to False enables
158 a wider set of coercion rules from string to non-string types for all
159 values. Default is True.
160 dec_hook : callable, optional
161 An optional callback for handling decoding custom types. Should have
162 the signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type``
163 is the expected message type, and ``obj`` is the decoded representation
164 composed of only basic TOML types. This hook should transform ``obj``
165 into type ``type``, or raise a ``NotImplementedError`` if unsupported.
167 Returns
168 -------
169 obj : Any
170 The deserialized object.
172 See Also
173 --------
174 encode
175 """
176 toml = _import_tomllib()
177 if isinstance(buf, str):
178 str_buf = buf
179 elif isinstance(buf, (bytes, bytearray)):
180 str_buf = buf.decode("utf-8")
181 else:
182 # call `memoryview` first, since `bytes(1)` is actually valid
183 str_buf = bytes(memoryview(buf)).decode("utf-8")
184 try:
185 obj = toml.loads(str_buf)
186 except toml.TOMLDecodeError as exc:
187 raise _DecodeError(str(exc)) from None
189 if type is Any:
190 return obj
191 return _convert(
192 obj,
193 type,
194 builtin_types=(_datetime.datetime, _datetime.date, _datetime.time),
195 str_keys=True,
196 strict=strict,
197 dec_hook=dec_hook,
198 )