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

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

109 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 Iterable 

9from typing import TypeVar 

10 

11from tomlkit._utils import parse_rfc3339 

12from tomlkit.container import Container 

13from tomlkit.exceptions import UnexpectedCharError 

14from tomlkit.items import CUSTOM_ENCODERS 

15from tomlkit.items import AoT 

16from tomlkit.items import Array 

17from tomlkit.items import Bool 

18from tomlkit.items import Comment 

19from tomlkit.items import Date 

20from tomlkit.items import DateTime 

21from tomlkit.items import DottedKey 

22from tomlkit.items import Encoder 

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 

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

41 """ 

42 Parses a string into a TOMLDocument. 

43 

44 Alias for parse(). 

45 """ 

46 return parse(string) 

47 

48 

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

50 """ 

51 Dumps a TOMLDocument into a string. 

52 """ 

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

54 data, Mapping 

55 ): 

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

57 

58 try: 

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

60 # for all type safe invocations of this function 

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

62 except AttributeError as ex: 

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

64 raise TypeError(msg) from ex 

65 

66 

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

68 """ 

69 Load toml document from a file-like object. 

70 """ 

71 return parse(fp.read()) 

72 

73 

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

75 """ 

76 Dump a TOMLDocument into a writable file stream. 

77 

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

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

80 

81 :Example: 

82 

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

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

85 """ 

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

87 

88 

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

90 """ 

91 Parses a string or bytes into a TOMLDocument. 

92 """ 

93 return Parser(string).parse() 

94 

95 

96def document() -> TOMLDocument: 

97 """ 

98 Returns a new TOMLDocument instance. 

99 """ 

100 return TOMLDocument() 

101 

102 

103# Items 

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

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

106 return item(int(raw)) 

107 

108 

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

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

111 return item(float(raw)) 

112 

113 

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

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

116 return item(raw == "true") 

117 

118 

119def string( 

120 raw: str, 

121 *, 

122 literal: bool = False, 

123 multiline: bool = False, 

124 escape: bool = True, 

125) -> String: 

126 """Create a string item. 

127 

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

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

130 can be used for personalization. 

131 

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

133 

134 Common escaping rules will be applied for basic strings. 

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

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

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

138 """ 

139 type_ = _StringType.select(literal, multiline) 

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

141 

142 

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

144 """Create a TOML date.""" 

145 value = parse_rfc3339(raw) 

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

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

148 

149 return item(value) 

150 

151 

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

153 """Create a TOML time.""" 

154 value = parse_rfc3339(raw) 

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

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

157 

158 return item(value) 

159 

160 

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

162 """Create a TOML datetime.""" 

163 value = parse_rfc3339(raw) 

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

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

166 

167 return item(value) 

168 

169 

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

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

172 

173 :Example: 

174 

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

176 [1, 2, 3] 

177 >>> a = array() 

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

179 >>> a 

180 [1, 2, 3] 

181 """ 

182 return value(raw) 

183 

184 

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

186 """Create an empty table. 

187 

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

189 

190 :Example: 

191 

192 >>> doc = document() 

193 >>> foo = table(True) 

194 >>> bar = table() 

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

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

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

198 >>> print(doc.as_string()) 

199 [foo.bar] 

200 x = 1 

201 """ 

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

203 

204 

205def inline_table() -> InlineTable: 

206 """Create an inline table. 

207 

208 :Example: 

209 

210 >>> table = inline_table() 

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

212 >>> print(table.as_string()) 

213 {x = 1, y = 2} 

214 """ 

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

216 

217 

218def aot() -> AoT: 

219 """Create an array of table. 

220 

221 :Example: 

222 

223 >>> doc = document() 

224 >>> aot = aot() 

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

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

227 >>> print(doc.as_string()) 

228 [[foo]] 

229 x = 1 

230 """ 

231 return AoT([]) 

232 

233 

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

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

236 it will create a dotted key. 

237 

238 :Example: 

239 

240 >>> doc = document() 

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

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

243 >>> print(doc.as_string()) 

244 foo = 1 

245 bar.baz = 2 

246 """ 

247 if isinstance(k, str): 

248 return SingleKey(k) 

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

250 

251 

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

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

254 

255 :Example: 

256 

257 >>> value("1") 

258 1 

259 >>> value("true") 

260 True 

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

262 [1, 2, 3] 

263 """ 

264 parser = Parser(raw) 

265 v = parser._parse_value() 

266 if not parser.end(): 

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

268 return v 

269 

270 

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

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

273 

274 :Example: 

275 

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

277 (Key('foo'), 1) 

278 """ 

279 return Parser(src)._parse_key_value() 

280 

281 

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

283 """Create a whitespace from a string.""" 

284 return Whitespace(src, fixed=True) 

285 

286 

287def nl() -> Whitespace: 

288 """Create a newline item.""" 

289 return ws("\n") 

290 

291 

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

293 """Create a comment item.""" 

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

295 

296 

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

298 

299 

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

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

302 if the value can't otherwise be converted. It should takes a single value 

303 and return a TOMLKit item or raise a ``ConvertError``. 

304 """ 

305 CUSTOM_ENCODERS.append(encoder) 

306 return encoder 

307 

308 

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

310 """Unregister a custom encoder.""" 

311 with contextlib.suppress(ValueError): 

312 CUSTOM_ENCODERS.remove(encoder)