Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/tomlkit/api.py: 58%

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

111 statements  

1from __future__ import annotations 

2 

3import contextlib 

4import datetime as _datetime 

5 

6from collections.abc import Mapping 

7from typing import IO 

8from typing import TYPE_CHECKING 

9from typing import Iterable 

10from typing import TypeVar 

11 

12from tomlkit._utils import parse_rfc3339 

13from tomlkit.container import Container 

14from tomlkit.exceptions import UnexpectedCharError 

15from tomlkit.items import CUSTOM_ENCODERS 

16from tomlkit.items import AoT 

17from tomlkit.items import Array 

18from tomlkit.items import Bool 

19from tomlkit.items import Comment 

20from tomlkit.items import Date 

21from tomlkit.items import DateTime 

22from tomlkit.items import DottedKey 

23from tomlkit.items import Float 

24from tomlkit.items import InlineTable 

25from tomlkit.items import Integer 

26from tomlkit.items import Item as _Item 

27from tomlkit.items import Key 

28from tomlkit.items import SingleKey 

29from tomlkit.items import String 

30from tomlkit.items import StringType as _StringType 

31from tomlkit.items import Table 

32from tomlkit.items import Time 

33from tomlkit.items import Trivia 

34from tomlkit.items import Whitespace 

35from tomlkit.items import item 

36from tomlkit.parser import Parser 

37from tomlkit.toml_document import TOMLDocument 

38 

39 

40if TYPE_CHECKING: 

41 from tomlkit.items import Encoder 

42 

43 E = TypeVar("E", bound=Encoder) 

44 

45 

46def loads(string: str | bytes) -> TOMLDocument: 

47 """ 

48 Parses a string into a TOMLDocument. 

49 

50 Alias for parse(). 

51 """ 

52 return parse(string) 

53 

54 

55def dumps(data: Mapping, sort_keys: bool = False) -> str: 

56 """ 

57 Dumps a TOMLDocument into a string. 

58 """ 

59 if not isinstance(data, (Table, InlineTable, Container)) and isinstance( 

60 data, Mapping 

61 ): 

62 data = item(dict(data), _sort_keys=sort_keys) 

63 

64 try: 

65 # data should be a `Container` (and therefore implement `as_string`) 

66 # for all type safe invocations of this function 

67 return data.as_string() # type: ignore[attr-defined] 

68 except AttributeError as ex: 

69 msg = f"Expecting Mapping or TOML Table or Container, {type(data)} given" 

70 raise TypeError(msg) from ex 

71 

72 

73def load(fp: IO[str] | IO[bytes]) -> TOMLDocument: 

74 """ 

75 Load toml document from a file-like object. 

76 """ 

77 return parse(fp.read()) 

78 

79 

80def dump(data: Mapping, fp: IO[str], *, sort_keys: bool = False) -> None: 

81 """ 

82 Dump a TOMLDocument into a writable file stream. 

83 

84 :param data: a dict-like object to dump 

85 :param sort_keys: if true, sort the keys in alphabetic order 

86 

87 :Example: 

88 

89 >>> with open("output.toml", "w") as fp: 

90 ... tomlkit.dump(data, fp) 

91 """ 

92 fp.write(dumps(data, sort_keys=sort_keys)) 

93 

94 

95def parse(string: str | bytes) -> TOMLDocument: 

96 """ 

97 Parses a string or bytes into a TOMLDocument. 

98 """ 

99 return Parser(string).parse() 

100 

101 

102def document() -> TOMLDocument: 

103 """ 

104 Returns a new TOMLDocument instance. 

105 """ 

106 return TOMLDocument() 

107 

108 

109# Items 

110def integer(raw: str | int) -> Integer: 

111 """Create an integer item from a number or string.""" 

112 return item(int(raw)) 

113 

114 

115def float_(raw: str | float) -> Float: 

116 """Create an float item from a number or string.""" 

117 return item(float(raw)) 

118 

119 

120def boolean(raw: str) -> Bool: 

121 """Turn `true` or `false` into a boolean item.""" 

122 return item(raw == "true") 

123 

124 

125def string( 

126 raw: str, 

127 *, 

128 literal: bool = False, 

129 multiline: bool = False, 

130 escape: bool = True, 

131) -> String: 

132 """Create a string item. 

133 

134 By default, this function will create *single line basic* strings, but 

135 boolean flags (e.g. ``literal=True`` and/or ``multiline=True``) 

136 can be used for personalization. 

137 

138 For more information, please check the spec: `<https://toml.io/en/v1.0.0#string>`__. 

139 

140 Common escaping rules will be applied for basic strings. 

141 This can be controlled by explicitly setting ``escape=False``. 

142 Please note that, if you disable escaping, you will have to make sure that 

143 the given strings don't contain any forbidden character or sequence. 

144 """ 

145 type_ = _StringType.select(literal, multiline) 

146 return String.from_raw(raw, type_, escape) 

147 

148 

149def date(raw: str) -> Date: 

150 """Create a TOML date.""" 

151 value = parse_rfc3339(raw) 

152 if not isinstance(value, _datetime.date): 

153 raise ValueError("date() only accepts date strings.") 

154 

155 return item(value) 

156 

157 

158def time(raw: str) -> Time: 

159 """Create a TOML time.""" 

160 value = parse_rfc3339(raw) 

161 if not isinstance(value, _datetime.time): 

162 raise ValueError("time() only accepts time strings.") 

163 

164 return item(value) 

165 

166 

167def datetime(raw: str) -> DateTime: 

168 """Create a TOML datetime.""" 

169 value = parse_rfc3339(raw) 

170 if not isinstance(value, _datetime.datetime): 

171 raise ValueError("datetime() only accepts datetime strings.") 

172 

173 return item(value) 

174 

175 

176def array(raw: str = "[]") -> Array: 

177 """Create an array item for its string representation. 

178 

179 :Example: 

180 

181 >>> array("[1, 2, 3]") # Create from a string 

182 [1, 2, 3] 

183 >>> a = array() 

184 >>> a.extend([1, 2, 3]) # Create from a list 

185 >>> a 

186 [1, 2, 3] 

187 """ 

188 return value(raw) 

189 

190 

191def table(is_super_table: bool | None = None) -> Table: 

192 """Create an empty table. 

193 

194 :param is_super_table: if true, the table is a super table 

195 

196 :Example: 

197 

198 >>> doc = document() 

199 >>> foo = table(True) 

200 >>> bar = table() 

201 >>> bar.update({'x': 1}) 

202 >>> foo.append('bar', bar) 

203 >>> doc.append('foo', foo) 

204 >>> print(doc.as_string()) 

205 [foo.bar] 

206 x = 1 

207 """ 

208 return Table(Container(), Trivia(), False, is_super_table) 

209 

210 

211def inline_table() -> InlineTable: 

212 """Create an inline table. 

213 

214 :Example: 

215 

216 >>> table = inline_table() 

217 >>> table.update({'x': 1, 'y': 2}) 

218 >>> print(table.as_string()) 

219 {x = 1, y = 2} 

220 """ 

221 return InlineTable(Container(), Trivia(), new=True) 

222 

223 

224def aot() -> AoT: 

225 """Create an array of table. 

226 

227 :Example: 

228 

229 >>> doc = document() 

230 >>> aot = aot() 

231 >>> aot.append(item({'x': 1})) 

232 >>> doc.append('foo', aot) 

233 >>> print(doc.as_string()) 

234 [[foo]] 

235 x = 1 

236 """ 

237 return AoT([]) 

238 

239 

240def key(k: str | Iterable[str]) -> Key: 

241 """Create a key from a string. When a list of string is given, 

242 it will create a dotted key. 

243 

244 :Example: 

245 

246 >>> doc = document() 

247 >>> doc.append(key('foo'), 1) 

248 >>> doc.append(key(['bar', 'baz']), 2) 

249 >>> print(doc.as_string()) 

250 foo = 1 

251 bar.baz = 2 

252 """ 

253 if isinstance(k, str): 

254 return SingleKey(k) 

255 return DottedKey([key(_k) for _k in k]) 

256 

257 

258def value(raw: str) -> _Item: 

259 """Parse a simple value from a string. 

260 

261 :Example: 

262 

263 >>> value("1") 

264 1 

265 >>> value("true") 

266 True 

267 >>> value("[1, 2, 3]") 

268 [1, 2, 3] 

269 """ 

270 parser = Parser(raw) 

271 v = parser._parse_value() 

272 if not parser.end(): 

273 raise parser.parse_error(UnexpectedCharError, char=parser._current) 

274 return v 

275 

276 

277def key_value(src: str) -> tuple[Key, _Item]: 

278 """Parse a key-value pair from a string. 

279 

280 :Example: 

281 

282 >>> key_value("foo = 1") 

283 (Key('foo'), 1) 

284 """ 

285 return Parser(src)._parse_key_value() 

286 

287 

288def ws(src: str) -> Whitespace: 

289 """Create a whitespace from a string.""" 

290 return Whitespace(src, fixed=True) 

291 

292 

293def nl() -> Whitespace: 

294 """Create a newline item.""" 

295 return ws("\n") 

296 

297 

298def comment(string: str) -> Comment: 

299 """Create a comment item.""" 

300 return Comment(Trivia(comment_ws=" ", comment="# " + string)) 

301 

302 

303def register_encoder(encoder: E) -> E: 

304 """Add a custom encoder, which should be a function that will be called 

305 if the value can't otherwise be converted. 

306 

307 The encoder should return a TOMLKit item or raise a ``ConvertError``. 

308 

309 Example: 

310 @register_encoder 

311 def encode_custom_dict(obj, _parent=None, _sort_keys=False): 

312 if isinstance(obj, CustomDict): 

313 tbl = table() 

314 for key, value in obj.items(): 

315 # Pass along parameters when encoding nested values 

316 tbl[key] = item(value, _parent=tbl, _sort_keys=_sort_keys) 

317 return tbl 

318 raise ConvertError("Not a CustomDict") 

319 """ 

320 CUSTOM_ENCODERS.append(encoder) 

321 return encoder 

322 

323 

324def unregister_encoder(encoder: Encoder) -> None: 

325 """Unregister a custom encoder.""" 

326 with contextlib.suppress(ValueError): 

327 CUSTOM_ENCODERS.remove(encoder)